mirror of
				https://github.com/cjcliffe/CubicSDR.git
				synced 2025-11-04 05:30:23 -05:00 
			
		
		
		
	Merge pull request #192 from cjcliffe/demod_refactor
Demodulator Refactor
This commit is contained in:
		
						commit
						3eb3ef4a74
					
				@ -2,8 +2,8 @@ cmake_minimum_required (VERSION 2.8)
 | 
			
		||||
 | 
			
		||||
SET(CUBICSDR_VERSION_MAJOR "0")
 | 
			
		||||
SET(CUBICSDR_VERSION_MINOR "1")
 | 
			
		||||
SET(CUBICSDR_VERSION_PATCH "16")
 | 
			
		||||
SET(CUBICSDR_VERSION_REL "alpha")
 | 
			
		||||
SET(CUBICSDR_VERSION_PATCH "17")
 | 
			
		||||
SET(CUBICSDR_VERSION_REL "alpha-demod-refactor")
 | 
			
		||||
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}-${CUBICSDR_VERSION_REL}")
 | 
			
		||||
 | 
			
		||||
SET(CPACK_PACKAGE_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}")
 | 
			
		||||
@ -234,6 +234,26 @@ SET (cubicsdr_sources
 | 
			
		||||
	src/demod/DemodulatorWorkerThread.cpp
 | 
			
		||||
	src/demod/DemodulatorInstance.cpp
 | 
			
		||||
	src/demod/DemodulatorMgr.cpp
 | 
			
		||||
    src/modules/modem/Modem.cpp
 | 
			
		||||
    src/modules/modem/ModemAnalog.cpp
 | 
			
		||||
    src/modules/modem/ModemDigital.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemASK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemAPSK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemBPSK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemDPSK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemPSK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemOOK.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemST.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemSQAM.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemQAM.cpp
 | 
			
		||||
    src/modules/modem/digital/ModemQPSK.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemAM.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemDSB.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemFM.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemFMStereo.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemIQ.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemLSB.cpp
 | 
			
		||||
    src/modules/modem/analog/ModemUSB.cpp
 | 
			
		||||
	src/audio/AudioThread.cpp
 | 
			
		||||
	src/util/Gradient.cpp
 | 
			
		||||
	src/util/Timer.cpp
 | 
			
		||||
@ -293,6 +313,26 @@ SET (cubicsdr_headers
 | 
			
		||||
	src/demod/DemodulatorInstance.h
 | 
			
		||||
	src/demod/DemodulatorMgr.h
 | 
			
		||||
	src/demod/DemodDefs.h
 | 
			
		||||
    src/modules/modem/Modem.h
 | 
			
		||||
    src/modules/modem/ModemAnalog.h
 | 
			
		||||
    src/modules/modem/ModemDigital.h
 | 
			
		||||
    src/modules/modem/digital/ModemASK.h
 | 
			
		||||
    src/modules/modem/digital/ModemAPSK.h
 | 
			
		||||
    src/modules/modem/digital/ModemBPSK.h
 | 
			
		||||
    src/modules/modem/digital/ModemDPSK.h
 | 
			
		||||
    src/modules/modem/digital/ModemPSK.h
 | 
			
		||||
    src/modules/modem/digital/ModemOOK.h
 | 
			
		||||
    src/modules/modem/digital/ModemST.h
 | 
			
		||||
    src/modules/modem/digital/ModemSQAM.h
 | 
			
		||||
    src/modules/modem/digital/ModemQAM.h
 | 
			
		||||
    src/modules/modem/digital/ModemQPSK.h
 | 
			
		||||
    src/modules/modem/analog/ModemAM.h
 | 
			
		||||
    src/modules/modem/analog/ModemDSB.h
 | 
			
		||||
    src/modules/modem/analog/ModemFM.h
 | 
			
		||||
    src/modules/modem/analog/ModemFMStereo.h
 | 
			
		||||
    src/modules/modem/analog/ModemIQ.h
 | 
			
		||||
    src/modules/modem/analog/ModemLSB.h
 | 
			
		||||
    src/modules/modem/analog/ModemUSB.h
 | 
			
		||||
	src/audio/AudioThread.h
 | 
			
		||||
	src/util/Gradient.h
 | 
			
		||||
	src/util/Timer.h
 | 
			
		||||
@ -372,6 +412,9 @@ SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION "src/demod/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Modem" REGULAR_EXPRESSION "src/modules/modem/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Modem-Analog" REGULAR_EXPRESSION "src/modules/modem/analog/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Modem-Digital" REGULAR_EXPRESSION "src/modules/modem/digital/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Audio" REGULAR_EXPRESSION "src/audio/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Utility" REGULAR_EXPRESSION "src/util/${REG_EXT}")
 | 
			
		||||
SOURCE_GROUP("Visual" REGULAR_EXPRESSION "src/visual/${REG_EXT}")
 | 
			
		||||
@ -387,6 +430,10 @@ include_directories (
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/sdr 
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/demod
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/modules
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/modules/modem
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/modules/modem/digital
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/modules/modem/analog
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/audio
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/util
 | 
			
		||||
	${PROJECT_SOURCE_DIR}/src/panel
 | 
			
		||||
 | 
			
		||||
@ -67,28 +67,29 @@ AppFrame::AppFrame() :
 | 
			
		||||
    gainSpacerItem->Show(false);
 | 
			
		||||
            
 | 
			
		||||
    demodModeSelector = new ModeSelectorCanvas(demodPanel, attribList);
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_FM, "FM");
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_AM, "AM");
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_LSB, "LSB");
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_USB, "USB");
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_DSB, "DSB");
 | 
			
		||||
    demodModeSelector->addChoice(DEMOD_TYPE_RAW, "I/Q");
 | 
			
		||||
    demodModeSelector->setSelection(DEMOD_TYPE_FM);
 | 
			
		||||
    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->setSelection("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->addChoice(0, "ASK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(1, "APSK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(2, "BPSK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(3, "DPSK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(4, "PSK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(5, "OOK");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(6, "ST");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(7, "SQAM");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(8, "QAM");
 | 
			
		||||
    demodModeSelectorAdv->addChoice(9, "QPSK");
 | 
			
		||||
    demodModeSelectorAdv->setHelpTip("Choose advanced modulation types.");
 | 
			
		||||
    demodTray->Add(demodModeSelectorAdv, 3, wxEXPAND | wxALL, 0);
 | 
			
		||||
    
 | 
			
		||||
@ -638,10 +639,9 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
 | 
			
		||||
    } else if (event.GetId() == wxID_RESET) {
 | 
			
		||||
        wxGetApp().getDemodMgr().terminateAll();
 | 
			
		||||
        wxGetApp().setFrequency(100000000);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastDemodulatorType(DEMOD_TYPE_FM);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastDemodulatorType("FM");
 | 
			
		||||
        demodModeSelector->setSelection(1);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastMuted(false);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastStereo(false);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastBandwidth(DEFAULT_DEMOD_BW);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastGain(1.0);
 | 
			
		||||
        wxGetApp().getDemodMgr().setLastSquelchLevel(0);
 | 
			
		||||
@ -855,7 +855,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
            int outputDevice = demod->getOutputDevice();
 | 
			
		||||
            scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
 | 
			
		||||
            outputDeviceMenuItems[outputDevice]->Check(true);
 | 
			
		||||
            int dType = demod->getDemodulatorType();
 | 
			
		||||
            std::string dType = demod->getDemodulatorType();
 | 
			
		||||
            demodModeSelector->setSelection(dType);
 | 
			
		||||
#ifdef ENABLE_DIGITAL_LAB
 | 
			
		||||
            int dCons = demod->getDemodulatorCons();
 | 
			
		||||
@ -868,12 +868,12 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
            long long centerFreq = demod->getFrequency();
 | 
			
		||||
            unsigned int demodBw = (unsigned int) ceil((float) demod->getBandwidth() * 2.25);
 | 
			
		||||
 | 
			
		||||
            if (demod->getDemodulatorType() == DEMOD_TYPE_USB) {
 | 
			
		||||
            if (demod->getDemodulatorType() == "USB") {
 | 
			
		||||
                demodBw /= 2;
 | 
			
		||||
                centerFreq += demod->getBandwidth() / 4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) {
 | 
			
		||||
            if (demod->getDemodulatorType() == "LSB") {
 | 
			
		||||
                demodBw /= 2;
 | 
			
		||||
                centerFreq -= demod->getBandwidth() / 4;
 | 
			
		||||
            }
 | 
			
		||||
@ -889,18 +889,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
                demodWaterfallCanvas->setCenterFrequency(centerFreq);
 | 
			
		||||
                demodSpectrumCanvas->setCenterFrequency(centerFreq);
 | 
			
		||||
            }
 | 
			
		||||
            int dSelection = demodModeSelector->getSelection();
 | 
			
		||||
            std::string dSelection = demodModeSelector->getSelectionLabel();
 | 
			
		||||
#ifdef ENABLE_DIGITAL_LAB
 | 
			
		||||
            int dSelectionadv = demodModeSelectorAdv->getSelection();
 | 
			
		||||
            std::string dSelectionadv = demodModeSelectorAdv->getSelectionLabel();
 | 
			
		||||
			int dSelectionCons = demodModeSelectorCons->getSelection();
 | 
			
		||||
 | 
			
		||||
            // basic demodulators
 | 
			
		||||
            if (dSelection != -1 && dSelection != demod->getDemodulatorType()) {
 | 
			
		||||
            if (dSelection != "" && dSelection != demod->getDemodulatorType()) {
 | 
			
		||||
                demod->setDemodulatorType(dSelection);
 | 
			
		||||
                demodModeSelectorAdv->setSelection(-1);
 | 
			
		||||
            }
 | 
			
		||||
            // advanced demodulators
 | 
			
		||||
			else if (dSelectionadv != -1 && dSelectionadv != demod->getDemodulatorType()) {
 | 
			
		||||
			else if (dSelectionadv != "" && dSelectionadv != demod->getDemodulatorType()) {
 | 
			
		||||
				demod->setDemodulatorType(dSelectionadv);
 | 
			
		||||
				demodModeSelector->setSelection(-1);
 | 
			
		||||
            }
 | 
			
		||||
@ -911,7 +911,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
			}
 | 
			
		||||
#else
 | 
			
		||||
            // basic demodulators
 | 
			
		||||
            if (dSelection != -1 && dSelection != demod->getDemodulatorType()) {
 | 
			
		||||
            if (dSelection != "" && dSelection != demod->getDemodulatorType()) {
 | 
			
		||||
                demod->setDemodulatorType(dSelection);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
@ -951,18 +951,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
    } else {
 | 
			
		||||
        DemodulatorMgr *mgr = &wxGetApp().getDemodMgr();
 | 
			
		||||
 | 
			
		||||
        int dSelection = demodModeSelector->getSelection();
 | 
			
		||||
        std::string dSelection = demodModeSelector->getSelectionLabel();
 | 
			
		||||
#ifdef ENABLE_DIGITAL_LAB
 | 
			
		||||
        int dSelectionadv = demodModeSelectorAdv->getSelection();
 | 
			
		||||
        std::string dSelectionadv = demodModeSelectorAdv->getSelectionLabel();
 | 
			
		||||
		int dSelectionCons = demodModeSelectorCons->getSelection();
 | 
			
		||||
 | 
			
		||||
        // basic demodulators
 | 
			
		||||
        if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) {
 | 
			
		||||
        if (dSelection != "" && dSelection != mgr->getLastDemodulatorType()) {
 | 
			
		||||
            mgr->setLastDemodulatorType(dSelection);
 | 
			
		||||
            demodModeSelectorAdv->setSelection(-1);
 | 
			
		||||
        }
 | 
			
		||||
        // advanced demodulators
 | 
			
		||||
        else if(dSelectionadv != -1 && dSelectionadv != mgr->getLastDemodulatorType()) {
 | 
			
		||||
        else if(dSelectionadv != "" && dSelectionadv != mgr->getLastDemodulatorType()) {
 | 
			
		||||
            mgr->setLastDemodulatorType(dSelectionadv);
 | 
			
		||||
            demodModeSelector->setSelection(-1);
 | 
			
		||||
        }
 | 
			
		||||
@ -973,7 +973,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
 | 
			
		||||
		}
 | 
			
		||||
#else
 | 
			
		||||
        // basic demodulators
 | 
			
		||||
        if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) {
 | 
			
		||||
        if (dSelection != "" && dSelection != mgr->getLastDemodulatorType()) {
 | 
			
		||||
            mgr->setLastDemodulatorType(dSelection);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
@ -1128,7 +1128,6 @@ void AppFrame::saveSession(std::string fileName) {
 | 
			
		||||
        *demod->newChild("type") = (*instance_i)->getDemodulatorType();
 | 
			
		||||
        *demod->newChild("squelch_level") = (*instance_i)->getSquelchLevel();
 | 
			
		||||
        *demod->newChild("squelch_enabled") = (*instance_i)->isSquelchEnabled() ? 1 : 0;
 | 
			
		||||
        *demod->newChild("stereo") = (*instance_i)->isStereo() ? 1 : 0;
 | 
			
		||||
        *demod->newChild("output_device") = outputDevices[(*instance_i)->getOutputDevice()].name;
 | 
			
		||||
        *demod->newChild("gain") = (*instance_i)->getGain();
 | 
			
		||||
        *demod->newChild("muted") = (*instance_i)->isMuted() ? 1 : 0;
 | 
			
		||||
@ -1175,14 +1174,32 @@ bool AppFrame::loadSession(std::string fileName) {
 | 
			
		||||
 | 
			
		||||
            long bandwidth = *demod->getNext("bandwidth");
 | 
			
		||||
            long long freq = *demod->getNext("frequency");
 | 
			
		||||
            int type = demod->hasAnother("type") ? *demod->getNext("type") : DEMOD_TYPE_FM;
 | 
			
		||||
            std::string type = demod->hasAnother("type") ? string(*demod->getNext("type")) : "FM";
 | 
			
		||||
            float squelch_level = demod->hasAnother("squelch_level") ? (float) *demod->getNext("squelch_level") : 0;
 | 
			
		||||
            int squelch_enabled = demod->hasAnother("squelch_enabled") ? (int) *demod->getNext("squelch_enabled") : 0;
 | 
			
		||||
            int stereo = demod->hasAnother("stereo") ? (int) *demod->getNext("stereo") : 0;
 | 
			
		||||
            int muted = demod->hasAnother("muted") ? (int) *demod->getNext("muted") : 0;
 | 
			
		||||
            std::string output_device = demod->hasAnother("output_device") ? string(*(demod->getNext("output_device"))) : "";
 | 
			
		||||
            float gain = demod->hasAnother("gain") ? (float) *demod->getNext("gain") : 1.0;
 | 
			
		||||
 | 
			
		||||
            // TODO: Check if "type" is numeric and perform update to new values
 | 
			
		||||
            //#define DEMOD_TYPE_NULL 0
 | 
			
		||||
            //#define DEMOD_TYPE_FM 1
 | 
			
		||||
            //#define DEMOD_TYPE_AM 2
 | 
			
		||||
            //#define DEMOD_TYPE_LSB 3
 | 
			
		||||
            //#define DEMOD_TYPE_USB 4
 | 
			
		||||
            //#define DEMOD_TYPE_DSB 5
 | 
			
		||||
            //#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
 | 
			
		||||
 | 
			
		||||
            DemodulatorInstance *newDemod = wxGetApp().getDemodMgr().newThread();
 | 
			
		||||
            loadedDemod = newDemod;
 | 
			
		||||
            numDemodulators++;
 | 
			
		||||
@ -1196,10 +1213,7 @@ bool AppFrame::loadSession(std::string fileName) {
 | 
			
		||||
                newDemod->setSquelchEnabled(true);
 | 
			
		||||
                newDemod->setSquelchLevel(squelch_level);
 | 
			
		||||
            }
 | 
			
		||||
            if (stereo) {
 | 
			
		||||
                newDemod->setStereo(true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
            bool found_device = false;
 | 
			
		||||
            std::map<int, RtAudio::DeviceInfo>::iterator i;
 | 
			
		||||
            for (i = outputDevices.begin(); i != outputDevices.end(); i++) {
 | 
			
		||||
@ -1221,7 +1235,6 @@ bool AppFrame::loadSession(std::string fileName) {
 | 
			
		||||
            std::cout << "\t\tBandwidth: " << bandwidth << std::endl;
 | 
			
		||||
            std::cout << "\t\tSquelch Level: " << squelch_level << std::endl;
 | 
			
		||||
            std::cout << "\t\tSquelch Enabled: " << (squelch_enabled ? "true" : "false") << std::endl;
 | 
			
		||||
            std::cout << "\t\tStereo: " << (stereo ? "true" : "false") << std::endl;
 | 
			
		||||
            std::cout << "\t\tOutput Device: " << output_device << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
@ -164,6 +164,25 @@ bool CubicSDR::OnInit() {
 | 
			
		||||
    
 | 
			
		||||
    wxApp::SetAppName("CubicSDR");
 | 
			
		||||
 | 
			
		||||
    Modem::addModemFactory(new ModemFM);
 | 
			
		||||
    Modem::addModemFactory(new ModemFMStereo);
 | 
			
		||||
    Modem::addModemFactory(new ModemAM);
 | 
			
		||||
    Modem::addModemFactory(new ModemLSB);
 | 
			
		||||
    Modem::addModemFactory(new ModemUSB);
 | 
			
		||||
    Modem::addModemFactory(new ModemDSB);
 | 
			
		||||
    Modem::addModemFactory(new ModemIQ);
 | 
			
		||||
 | 
			
		||||
    Modem::addModemFactory(new ModemAPSK);
 | 
			
		||||
    Modem::addModemFactory(new ModemASK);
 | 
			
		||||
    Modem::addModemFactory(new ModemBPSK);
 | 
			
		||||
    Modem::addModemFactory(new ModemDPSK);
 | 
			
		||||
    Modem::addModemFactory(new ModemOOK);
 | 
			
		||||
    Modem::addModemFactory(new ModemPSK);
 | 
			
		||||
    Modem::addModemFactory(new ModemQAM);
 | 
			
		||||
    Modem::addModemFactory(new ModemQPSK);
 | 
			
		||||
    Modem::addModemFactory(new ModemSQAM);
 | 
			
		||||
    Modem::addModemFactory(new ModemST);
 | 
			
		||||
 | 
			
		||||
    frequency = wxGetApp().getConfig()->getCenterFreq();
 | 
			
		||||
    offset = 0;
 | 
			
		||||
    ppm = 0;
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,26 @@
 | 
			
		||||
#include "SpectrumVisualProcessor.h"
 | 
			
		||||
#include "SpectrumVisualDataThread.h"
 | 
			
		||||
#include "SDRDevices.h"
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
#include "ModemFM.h"
 | 
			
		||||
#include "ModemFMStereo.h"
 | 
			
		||||
#include "ModemAM.h"
 | 
			
		||||
#include "ModemUSB.h"
 | 
			
		||||
#include "ModemLSB.h"
 | 
			
		||||
#include "ModemDSB.h"
 | 
			
		||||
#include "ModemIQ.h"
 | 
			
		||||
 | 
			
		||||
#include "ModemAPSK.h"
 | 
			
		||||
#include "ModemASK.h"
 | 
			
		||||
#include "ModemBPSK.h"
 | 
			
		||||
#include "ModemDPSK.h"
 | 
			
		||||
#include "ModemOOK.h"
 | 
			
		||||
#include "ModemPSK.h"
 | 
			
		||||
#include "ModemQAM.h"
 | 
			
		||||
#include "ModemQPSK.h"
 | 
			
		||||
#include "ModemSQAM.h"
 | 
			
		||||
#include "ModemST.h"
 | 
			
		||||
 | 
			
		||||
#include <wx/cmdline.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ const char filePathSeparator =
 | 
			
		||||
#define DEFAULT_SAMPLE_RATE 2500000
 | 
			
		||||
#define DEFAULT_FFT_SIZE 2048
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_DEMOD_TYPE 1
 | 
			
		||||
#define DEFAULT_DEMOD_TYPE "FM"
 | 
			
		||||
#define DEFAULT_DEMOD_BW 200000
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_WATERFALL_LPS 30
 | 
			
		||||
 | 
			
		||||
@ -7,24 +7,6 @@
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
#define DEMOD_TYPE_NULL 0
 | 
			
		||||
#define DEMOD_TYPE_FM 1
 | 
			
		||||
#define DEMOD_TYPE_AM 2
 | 
			
		||||
#define DEMOD_TYPE_LSB 3
 | 
			
		||||
#define DEMOD_TYPE_USB 4
 | 
			
		||||
#define DEMOD_TYPE_DSB 5
 | 
			
		||||
#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"
 | 
			
		||||
 | 
			
		||||
class DemodulatorThread;
 | 
			
		||||
@ -62,11 +44,11 @@ public:
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadControlCommand() :
 | 
			
		||||
            cmd(DEMOD_THREAD_CMD_CTL_NULL), demodType(DEMOD_TYPE_NULL) {
 | 
			
		||||
            cmd(DEMOD_THREAD_CMD_CTL_NULL), demodType("") {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadControlCommandEnum cmd;
 | 
			
		||||
    int demodType;
 | 
			
		||||
    std::string demodType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DemodulatorThreadIQData: public ReferenceCounter {
 | 
			
		||||
@ -93,21 +75,19 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Modem;
 | 
			
		||||
class ModemKit;
 | 
			
		||||
 | 
			
		||||
class DemodulatorThreadPostIQData: public ReferenceCounter {
 | 
			
		||||
public:
 | 
			
		||||
    std::vector<liquid_float_complex> data;
 | 
			
		||||
    long long sampleRate;
 | 
			
		||||
    msresamp_rrrf audioResampler;
 | 
			
		||||
    msresamp_rrrf stereoResampler;
 | 
			
		||||
    double audioResampleRatio;
 | 
			
		||||
    int audioSampleRate;
 | 
			
		||||
 | 
			
		||||
    firfilt_rrrf firStereoLeft;
 | 
			
		||||
    firfilt_rrrf firStereoRight;
 | 
			
		||||
    iirfilt_crcf iirStereoPilot;
 | 
			
		||||
    std::string modemType;
 | 
			
		||||
    Modem *modem;
 | 
			
		||||
    ModemKit *modemKit;
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadPostIQData() :
 | 
			
		||||
            sampleRate(0), audioResampler(NULL), stereoResampler(NULL), audioResampleRatio(0), audioSampleRate(0), firStereoLeft(NULL), firStereoRight(NULL), iirStereoPilot(NULL) {
 | 
			
		||||
            sampleRate(0), modem(nullptr), modemKit(nullptr) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -116,6 +96,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DemodulatorThreadAudioData: public ReferenceCounter {
 | 
			
		||||
public:
 | 
			
		||||
    long long frequency;
 | 
			
		||||
@ -151,11 +132,11 @@ public:
 | 
			
		||||
    unsigned int bandwidth; // set equal to disable second stage re-sampling?
 | 
			
		||||
    unsigned int audioSampleRate;
 | 
			
		||||
 | 
			
		||||
    int demodType;
 | 
			
		||||
    std::string demodType;
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadParameters() :
 | 
			
		||||
            frequency(0), sampleRate(DEFAULT_SAMPLE_RATE), bandwidth(200000), audioSampleRate(0),
 | 
			
		||||
            demodType(DEMOD_TYPE_FM) {
 | 
			
		||||
            demodType("FM") {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,6 @@ DemodulatorInstance::DemodulatorInstance() :
 | 
			
		||||
	preDemodTerminated.store(true);
 | 
			
		||||
	active.store(false);
 | 
			
		||||
	squelch.store(false);
 | 
			
		||||
	stereo.store(false);
 | 
			
		||||
    muted.store(false);
 | 
			
		||||
	tracking.store(false);
 | 
			
		||||
	follow.store(false);
 | 
			
		||||
@ -34,7 +33,7 @@ DemodulatorInstance::DemodulatorInstance() :
 | 
			
		||||
    pipeAudioData = new AudioThreadInputQueue;
 | 
			
		||||
    threadQueueControl = new DemodulatorThreadControlCommandQueue;
 | 
			
		||||
 | 
			
		||||
    demodulatorThread = new DemodulatorThread();
 | 
			
		||||
    demodulatorThread = new DemodulatorThread(this);
 | 
			
		||||
    demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData);
 | 
			
		||||
    demodulatorThread->setInputQueue("ControlQueue",threadQueueControl);
 | 
			
		||||
    demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
 | 
			
		||||
@ -44,8 +43,7 @@ DemodulatorInstance::DemodulatorInstance() :
 | 
			
		||||
    audioThread->setInputQueue("AudioDataInput", pipeAudioData);
 | 
			
		||||
    audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
 | 
			
		||||
 | 
			
		||||
    currentDemodType = demodulatorThread->getDemodulatorType();
 | 
			
		||||
    currentDemodCons = demodulatorThread->getDemodulatorCons();
 | 
			
		||||
    currentDemodType = demodulatorPreThread->getParams().demodType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DemodulatorInstance::~DemodulatorInstance() {
 | 
			
		||||
@ -74,10 +72,9 @@ void DemodulatorInstance::run() {
 | 
			
		||||
//    }
 | 
			
		||||
 | 
			
		||||
    currentFrequency = demodulatorPreThread->getParams().frequency;
 | 
			
		||||
    currentDemodType = demodulatorThread->getDemodulatorType();
 | 
			
		||||
    currentDemodCons = demodulatorThread->getDemodulatorCons();
 | 
			
		||||
    currentAudioSampleRate = AudioThread::deviceSampleRate[getOutputDevice()];
 | 
			
		||||
    demodulatorPreThread->getParams().audioSampleRate = currentAudioSampleRate;
 | 
			
		||||
    setDemodulatorType(demodulatorPreThread->getParams().demodType);
 | 
			
		||||
 | 
			
		||||
    t_Audio = new std::thread(&AudioThread::threadMain, audioThread);
 | 
			
		||||
 | 
			
		||||
@ -103,6 +100,7 @@ void DemodulatorInstance::run() {
 | 
			
		||||
    t_PreDemod = new std::thread(&DemodulatorPreThread::threadMain, demodulatorPreThread);
 | 
			
		||||
    t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    active = true;
 | 
			
		||||
    audioTerminated = demodTerminated = preDemodTerminated = terminated = false;
 | 
			
		||||
 | 
			
		||||
@ -196,15 +194,6 @@ void DemodulatorInstance::setActive(bool state) {
 | 
			
		||||
    active = state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DemodulatorInstance::isStereo() {
 | 
			
		||||
    return stereo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::setStereo(bool state) {
 | 
			
		||||
    stereo = state;
 | 
			
		||||
    demodulatorThread->setStereo(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::squelchAuto() {
 | 
			
		||||
    DemodulatorThreadControlCommand command;
 | 
			
		||||
    command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_ON;
 | 
			
		||||
@ -271,57 +260,69 @@ void DemodulatorInstance::checkBandwidth() {
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::setDemodulatorType(int demod_type_in) {
 | 
			
		||||
void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
 | 
			
		||||
    currentDemodType = demod_type_in;
 | 
			
		||||
 | 
			
		||||
    if (currentDemodType == DEMOD_TYPE_RAW) {
 | 
			
		||||
    if (currentDemodType == "I/Q") {
 | 
			
		||||
        if (currentAudioSampleRate) {
 | 
			
		||||
            setBandwidth(currentAudioSampleRate);
 | 
			
		||||
        } else {
 | 
			
		||||
            setBandwidth(AudioThread::deviceSampleRate[getOutputDevice()]);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (currentDemodType == DEMOD_TYPE_USB || currentDemodType == DEMOD_TYPE_LSB || currentDemodType == DEMOD_TYPE_DSB || currentDemodType == DEMOD_TYPE_AM) {
 | 
			
		||||
    } else if (currentDemodType == "USB" || currentDemodType == "LSB" || currentDemodType == "DSB" || currentDemodType == "AM") {
 | 
			
		||||
    	demodulatorThread->setAGC(false);
 | 
			
		||||
    } else {
 | 
			
		||||
    	demodulatorThread->setAGC(true);
 | 
			
		||||
    }
 | 
			
		||||
    setGain(getGain());
 | 
			
		||||
 | 
			
		||||
    demodulatorPreThread->getParams().demodType = currentDemodType;
 | 
			
		||||
    if (!active) {
 | 
			
		||||
        checkBandwidth();
 | 
			
		||||
        demodulatorPreThread->getParams().demodType = currentDemodType;
 | 
			
		||||
        demodulatorThread->setDemodulatorType(currentDemodType);
 | 
			
		||||
        demodulatorPreThread->setDemodType(currentDemodType);
 | 
			
		||||
    } else if (demodulatorThread && threadQueueControl) {
 | 
			
		||||
        DemodulatorThreadControlCommand command;
 | 
			
		||||
        command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_TYPE;
 | 
			
		||||
        command.demodType = demod_type_in;
 | 
			
		||||
        checkBandwidth();
 | 
			
		||||
        threadQueueControl->push(command);
 | 
			
		||||
        demodulatorPreThread->setDemodType(currentDemodType);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DemodulatorInstance::getDemodulatorType() {
 | 
			
		||||
std::string DemodulatorInstance::getDemodulatorType() {
 | 
			
		||||
    return currentDemodType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::setDemodulatorLock(bool demod_lock_in) {
 | 
			
		||||
    demodulatorThread->setDemodulatorLock(demod_lock_in);
 | 
			
		||||
    Modem *cModem = demodulatorPreThread->getModem();
 | 
			
		||||
    if (cModem && cModem->getType() == "digital") {
 | 
			
		||||
        ((ModemDigital *)cModem)->setDemodulatorLock(demod_lock_in);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DemodulatorInstance::getDemodulatorLock() {
 | 
			
		||||
    return demodulatorThread->getDemodulatorLock();
 | 
			
		||||
    Modem *cModem = demodulatorPreThread->getModem();
 | 
			
		||||
 | 
			
		||||
    if (cModem && cModem->getType() == "digital") {
 | 
			
		||||
        return ((ModemDigital *)cModem)->getDemodulatorLock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::setDemodulatorCons(int demod_cons_in) {
 | 
			
		||||
    demodulatorThread->setDemodulatorCons(demod_cons_in);
 | 
			
		||||
    Modem *cModem = demodulatorPreThread->getModem();
 | 
			
		||||
    if (cModem && cModem->getType() == "digital") {
 | 
			
		||||
        ((ModemDigital *)cModem)->setDemodulatorCons(demod_cons_in);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DemodulatorInstance::getDemodulatorCons() {
 | 
			
		||||
    return demodulatorThread->getDemodulatorCons();
 | 
			
		||||
    Modem *cModem = demodulatorPreThread->getModem();
 | 
			
		||||
    if (cModem && cModem->getType() == "digital") {
 | 
			
		||||
        return ((ModemDigital *)cModem)->getDemodulatorCons();
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorInstance::setBandwidth(int bw) {
 | 
			
		||||
    if (currentDemodType == DEMOD_TYPE_RAW) {
 | 
			
		||||
    if (currentDemodType == "I/Q") {
 | 
			
		||||
        if (currentAudioSampleRate) {
 | 
			
		||||
            bw = currentAudioSampleRate;
 | 
			
		||||
        } else {
 | 
			
		||||
@ -384,7 +385,7 @@ void DemodulatorInstance::setAudioSampleRate(int sampleRate) {
 | 
			
		||||
        command.llong_value = sampleRate;
 | 
			
		||||
        pipeDemodCommand->push(command);
 | 
			
		||||
    }
 | 
			
		||||
    if (currentDemodType == DEMOD_TYPE_RAW) {
 | 
			
		||||
    if (currentDemodType == "I/Q") {
 | 
			
		||||
        setBandwidth(currentAudioSampleRate);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -400,7 +401,7 @@ int DemodulatorInstance::getAudioSampleRate() {
 | 
			
		||||
void DemodulatorInstance::setGain(float gain_in) {
 | 
			
		||||
	currentAudioGain = gain_in;
 | 
			
		||||
 | 
			
		||||
    if (currentDemodType == DEMOD_TYPE_RAW) {
 | 
			
		||||
    if (currentDemodType == "I/Q") {
 | 
			
		||||
		if (gain_in < 0.25) {
 | 
			
		||||
		    audioThread->setGain(1.0);
 | 
			
		||||
			demodulatorThread->setAGC(false);
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,9 @@
 | 
			
		||||
#include "DemodulatorThread.h"
 | 
			
		||||
#include "DemodulatorPreThread.h"
 | 
			
		||||
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class DemodulatorInstance {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@ -39,9 +42,6 @@ public:
 | 
			
		||||
    bool isActive();
 | 
			
		||||
    void setActive(bool state);
 | 
			
		||||
 | 
			
		||||
    bool isStereo();
 | 
			
		||||
    void setStereo(bool state);
 | 
			
		||||
 | 
			
		||||
    void squelchAuto();
 | 
			
		||||
    bool isSquelchEnabled();
 | 
			
		||||
    void setSquelchEnabled(bool state);
 | 
			
		||||
@ -53,8 +53,8 @@ public:
 | 
			
		||||
    void setOutputDevice(int device_id);
 | 
			
		||||
    int getOutputDevice();
 | 
			
		||||
 | 
			
		||||
    void setDemodulatorType(int demod_type_in);
 | 
			
		||||
    int getDemodulatorType();
 | 
			
		||||
    void setDemodulatorType(std::string demod_type_in);
 | 
			
		||||
    std::string getDemodulatorType();
 | 
			
		||||
    
 | 
			
		||||
    void setDemodulatorLock(bool demod_lock_in);
 | 
			
		||||
    int getDemodulatorLock();
 | 
			
		||||
@ -98,7 +98,7 @@ protected:
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void checkBandwidth();
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    std::atomic<std::string *> label; //
 | 
			
		||||
    std::atomic_bool terminated; //
 | 
			
		||||
    std::atomic_bool demodTerminated; //
 | 
			
		||||
@ -106,13 +106,11 @@ private:
 | 
			
		||||
    std::atomic_bool preDemodTerminated;
 | 
			
		||||
    std::atomic_bool active;
 | 
			
		||||
    std::atomic_bool squelch;
 | 
			
		||||
    std::atomic_bool stereo;
 | 
			
		||||
    std::atomic_bool muted;
 | 
			
		||||
 | 
			
		||||
    std::atomic_llong currentFrequency;
 | 
			
		||||
    std::atomic_int currentBandwidth;
 | 
			
		||||
    std::atomic_int currentDemodType;
 | 
			
		||||
    std::atomic_int currentDemodCons;
 | 
			
		||||
    std::string currentDemodType;
 | 
			
		||||
    std::atomic_int currentOutputDevice;
 | 
			
		||||
    std::atomic_int currentAudioSampleRate;
 | 
			
		||||
    std::atomic<float> currentAudioGain;
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 | 
			
		||||
DemodulatorMgr::DemodulatorMgr() :
 | 
			
		||||
        activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL), lastBandwidth(DEFAULT_DEMOD_BW), lastDemodType(
 | 
			
		||||
                DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(0), lastGain(1.0), lastStereo(false), lastMuted(false) {
 | 
			
		||||
                DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(0), lastGain(1.0), lastMuted(false) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(long long
 | 
			
		||||
 | 
			
		||||
        long long halfBuffer = bandwidth / 2;
 | 
			
		||||
 | 
			
		||||
        if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != DEMOD_TYPE_LSB)?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != DEMOD_TYPE_USB)?halfBandwidthTest:0) - halfBuffer))) {
 | 
			
		||||
        if ((freq <= (freqTest + ((testDemod->getDemodulatorType() != "LSB")?halfBandwidthTest:0) + halfBuffer)) && (freq >= (freqTest - ((testDemod->getDemodulatorType() != "USB")?halfBandwidthTest:0) - halfBuffer))) {
 | 
			
		||||
            foundDemods->push_back(testDemod);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -166,7 +166,6 @@ void DemodulatorMgr::updateLastState() {
 | 
			
		||||
        lastSquelchEnabled = lastActiveDemodulator->isSquelchEnabled();
 | 
			
		||||
        lastSquelch = lastActiveDemodulator->getSquelchLevel();
 | 
			
		||||
        lastGain = lastActiveDemodulator->getGain();
 | 
			
		||||
        lastStereo = lastActiveDemodulator->isStereo();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -184,11 +183,11 @@ void DemodulatorMgr::setLastBandwidth(int lastBandwidth) {
 | 
			
		||||
    this->lastBandwidth = lastBandwidth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DemodulatorMgr::getLastDemodulatorType() const {
 | 
			
		||||
std::string DemodulatorMgr::getLastDemodulatorType() const {
 | 
			
		||||
    return lastDemodType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorMgr::setLastDemodulatorType(int lastDemodType) {
 | 
			
		||||
void DemodulatorMgr::setLastDemodulatorType(std::string lastDemodType) {
 | 
			
		||||
    this->lastDemodType = lastDemodType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -224,15 +223,6 @@ void DemodulatorMgr::setLastSquelchEnabled(bool lastSquelchEnabled) {
 | 
			
		||||
    this->lastSquelchEnabled = lastSquelchEnabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DemodulatorMgr::isLastStereo() const {
 | 
			
		||||
    return lastStereo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorMgr::setLastStereo(bool lastStereo) {
 | 
			
		||||
    this->lastStereo = lastStereo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool DemodulatorMgr::isLastMuted() const {
 | 
			
		||||
    return lastMuted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,8 @@ public:
 | 
			
		||||
    int getLastBandwidth() const;
 | 
			
		||||
    void setLastBandwidth(int lastBandwidth);
 | 
			
		||||
 | 
			
		||||
    int getLastDemodulatorType() const;
 | 
			
		||||
    void setLastDemodulatorType(int lastDemodType);
 | 
			
		||||
    std::string getLastDemodulatorType() const;
 | 
			
		||||
    void setLastDemodulatorType(std::string lastDemodType);
 | 
			
		||||
    
 | 
			
		||||
    int getLastDemodulatorCons() const;
 | 
			
		||||
    void setLastDemodulatorCons(int lastDemodCons);
 | 
			
		||||
@ -39,10 +39,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    bool isLastSquelchEnabled() const;
 | 
			
		||||
    void setLastSquelchEnabled(bool lastSquelchEnabled);
 | 
			
		||||
 | 
			
		||||
    bool isLastStereo() const;
 | 
			
		||||
    void setLastStereo(bool lastStereo);
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    bool isLastMuted() const;
 | 
			
		||||
    void setLastMuted(bool lastMuted);
 | 
			
		||||
 | 
			
		||||
@ -57,11 +54,11 @@ private:
 | 
			
		||||
    DemodulatorInstance *activeVisualDemodulator;
 | 
			
		||||
 | 
			
		||||
    int lastBandwidth;
 | 
			
		||||
    int lastDemodType;
 | 
			
		||||
    std::string lastDemodType;
 | 
			
		||||
    bool lastDemodLock;
 | 
			
		||||
    int lastDemodCons;
 | 
			
		||||
    bool lastSquelchEnabled;
 | 
			
		||||
    float lastSquelch;
 | 
			
		||||
    float lastGain;
 | 
			
		||||
    bool lastStereo, lastMuted;
 | 
			
		||||
    bool lastMuted;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
#include "DemodulatorPreThread.h"
 | 
			
		||||
#include "CubicSDR.h"
 | 
			
		||||
 | 
			
		||||
DemodulatorPreThread::DemodulatorPreThread() : IOThread(), iqResampler(NULL), iqResampleRatio(1), audioResampler(NULL), stereoResampler(NULL), audioResampleRatio(1), firStereoLeft(NULL), firStereoRight(NULL), iirStereoPilot(NULL), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL), commandQueue(NULL)
 | 
			
		||||
DemodulatorPreThread::DemodulatorPreThread() : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL), commandQueue(NULL)
 | 
			
		||||
 {
 | 
			
		||||
	initialized.store(false);
 | 
			
		||||
 | 
			
		||||
@ -24,50 +24,14 @@ DemodulatorPreThread::DemodulatorPreThread() : IOThread(), iqResampler(NULL), iq
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorPreThread::initialize() {
 | 
			
		||||
    initialized = false;
 | 
			
		||||
 | 
			
		||||
    iqResampleRatio = (double) (params.bandwidth) / (double) params.sampleRate;
 | 
			
		||||
    audioResampleRatio = (double) (params.audioSampleRate) / (double) params.bandwidth;
 | 
			
		||||
 | 
			
		||||
    float As = 120.0f;         // stop-band attenuation [dB]
 | 
			
		||||
    float As = 60.0f;         // stop-band attenuation [dB]
 | 
			
		||||
 | 
			
		||||
    iqResampler = msresamp_crcf_create(iqResampleRatio, As);
 | 
			
		||||
    audioResampler = msresamp_rrrf_create(audioResampleRatio, As);
 | 
			
		||||
    stereoResampler = msresamp_rrrf_create(audioResampleRatio, As);
 | 
			
		||||
 | 
			
		||||
    // Stereo filters / shifters
 | 
			
		||||
    double firStereoCutoff = ((double) 16000 / (double) params.audioSampleRate);
 | 
			
		||||
    float ft = ((double) 1000 / (double) params.audioSampleRate);         // filter transition
 | 
			
		||||
    float mu = 0.0f;         // fractional timing offset
 | 
			
		||||
 | 
			
		||||
    if (firStereoCutoff < 0) {
 | 
			
		||||
        firStereoCutoff = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (firStereoCutoff > 0.5) {
 | 
			
		||||
        firStereoCutoff = 0.5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned int h_len = estimate_req_filter_len(ft, As);
 | 
			
		||||
    float *h = new float[h_len];
 | 
			
		||||
    liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h);
 | 
			
		||||
 | 
			
		||||
    firStereoLeft = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
    firStereoRight = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
 | 
			
		||||
    // stereo pilot filter
 | 
			
		||||
    float bw = params.bandwidth;
 | 
			
		||||
    if (bw < 100000.0) {
 | 
			
		||||
        bw = 100000.0;
 | 
			
		||||
    }
 | 
			
		||||
    unsigned int order =   5;       // filter order
 | 
			
		||||
    float        f0    =   ((double) 19000 / bw);
 | 
			
		||||
    float        fc    =   ((double) 19500 / bw);
 | 
			
		||||
    float        Ap    =   1.0f;
 | 
			
		||||
    As    =  60.0f;
 | 
			
		||||
    iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As);
 | 
			
		||||
 | 
			
		||||
    initialized = true;
 | 
			
		||||
    initialized.store(true);
 | 
			
		||||
    
 | 
			
		||||
    lastParams = params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -88,8 +52,6 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
 | 
			
		||||
    std::cout << "Demodulator preprocessor thread started.." << std::endl;
 | 
			
		||||
 | 
			
		||||
    t_Worker = new std::thread(&DemodulatorWorkerThread::threadMain, workerThread);
 | 
			
		||||
 | 
			
		||||
    ReBuffer<DemodulatorThreadPostIQData> buffers;
 | 
			
		||||
 | 
			
		||||
    iqInputQueue = (DemodulatorThreadInputQueue*)getInputQueue("IQDataInput");
 | 
			
		||||
@ -99,9 +61,10 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
    
 | 
			
		||||
    std::vector<liquid_float_complex> in_buf_data;
 | 
			
		||||
    std::vector<liquid_float_complex> out_buf_data;
 | 
			
		||||
//    liquid_float_complex carrySample;   // Keep the stream count even to simplify some demod operations
 | 
			
		||||
//    bool carrySampleFlag = false;
 | 
			
		||||
 | 
			
		||||
    setDemodType(params.demodType);
 | 
			
		||||
    t_Worker = new std::thread(&DemodulatorWorkerThread::threadMain, workerThread);
 | 
			
		||||
    
 | 
			
		||||
    while (!terminated) {
 | 
			
		||||
        DemodulatorThreadIQData *inp;
 | 
			
		||||
        iqInputQueue->pop(inp);
 | 
			
		||||
@ -218,40 +181,11 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
            msresamp_crcf_execute(iqResampler, in_buf, bufSize, &resampledData[0], &numWritten);
 | 
			
		||||
 | 
			
		||||
            resamp->setRefCount(1);
 | 
			
		||||
 | 
			
		||||
            resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten);
 | 
			
		||||
 | 
			
		||||
//            bool uneven = (numWritten % 2 != 0);
 | 
			
		||||
 | 
			
		||||
//            if (!carrySampleFlag && !uneven) {
 | 
			
		||||
//                resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten);
 | 
			
		||||
//                carrySampleFlag = false;
 | 
			
		||||
//            } else if (!carrySampleFlag && uneven) {
 | 
			
		||||
//                resamp->data.assign(resampledData.begin(), resampledData.begin() + (numWritten-1));
 | 
			
		||||
//                carrySample = resampledData.back();
 | 
			
		||||
//                carrySampleFlag = true;
 | 
			
		||||
//            } else if (carrySampleFlag && uneven) {
 | 
			
		||||
//                resamp->data.resize(numWritten+1);
 | 
			
		||||
//                resamp->data[0] = carrySample;
 | 
			
		||||
//                memcpy(&resamp->data[1],&resampledData[0],sizeof(liquid_float_complex)*numWritten);
 | 
			
		||||
//                carrySampleFlag = false;
 | 
			
		||||
//            } else if (carrySampleFlag && !uneven) {
 | 
			
		||||
//                resamp->data.resize(numWritten);
 | 
			
		||||
//                resamp->data[0] = carrySample;
 | 
			
		||||
//                memcpy(&resamp->data[1],&resampledData[0],sizeof(liquid_float_complex)*(numWritten-1));
 | 
			
		||||
//                carrySample = resampledData.back();
 | 
			
		||||
//                carrySampleFlag = true;
 | 
			
		||||
//            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            resamp->audioResampleRatio = audioResampleRatio;
 | 
			
		||||
            resamp->audioResampler = audioResampler;
 | 
			
		||||
            resamp->audioSampleRate = params.audioSampleRate;
 | 
			
		||||
            resamp->stereoResampler = stereoResampler;
 | 
			
		||||
            resamp->firStereoLeft = firStereoLeft;
 | 
			
		||||
            resamp->firStereoRight = firStereoRight;
 | 
			
		||||
            resamp->iirStereoPilot = iirStereoPilot;
 | 
			
		||||
            resamp->modemType = demodType;
 | 
			
		||||
            resamp->modem = cModem;
 | 
			
		||||
            resamp->modemKit = cModemKit;
 | 
			
		||||
            resamp->sampleRate = params.bandwidth;
 | 
			
		||||
 | 
			
		||||
            iqOutputQueue->push(resamp);
 | 
			
		||||
@ -266,35 +200,23 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
 | 
			
		||||
                switch (result.cmd) {
 | 
			
		||||
                case DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS:
 | 
			
		||||
                    msresamp_crcf_destroy(iqResampler);
 | 
			
		||||
 | 
			
		||||
                    if (result.iqResampler) {
 | 
			
		||||
                        if (iqResampler) {
 | 
			
		||||
                            msresamp_crcf_destroy(iqResampler);
 | 
			
		||||
                        }
 | 
			
		||||
                        iqResampler = result.iqResampler;
 | 
			
		||||
                        iqResampleRatio = result.iqResampleRatio;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (result.firStereoLeft) {
 | 
			
		||||
                        firStereoLeft = result.firStereoLeft;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (result.firStereoRight) {
 | 
			
		||||
                        firStereoRight = result.firStereoRight;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (result.iirStereoPilot) {
 | 
			
		||||
                        iirStereoPilot = result.iirStereoPilot;
 | 
			
		||||
                    if (result.modem != nullptr) {
 | 
			
		||||
                        cModem = result.modem;
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    if (result.audioResampler) {
 | 
			
		||||
                        audioResampler = result.audioResampler;
 | 
			
		||||
                        audioResampleRatio = result.audioResamplerRatio;
 | 
			
		||||
                        stereoResampler = result.stereoResampler;
 | 
			
		||||
                    if (result.modemKit != nullptr) {
 | 
			
		||||
                        cModemKit = result.modemKit;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (result.audioSampleRate) {
 | 
			
		||||
                        params.audioSampleRate = result.audioSampleRate;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
                    if (result.bandwidth) {
 | 
			
		||||
                        params.bandwidth = result.bandwidth;
 | 
			
		||||
                    }
 | 
			
		||||
@ -302,6 +224,12 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
                    if (result.sampleRate) {
 | 
			
		||||
                        params.sampleRate = result.sampleRate;
 | 
			
		||||
                    }
 | 
			
		||||
                        
 | 
			
		||||
                    if (result.modemType != "") {
 | 
			
		||||
                        demodType = result.modemType;
 | 
			
		||||
                        params.demodType = result.modemType;
 | 
			
		||||
                        demodTypeChanged.store(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
@ -318,6 +246,31 @@ void DemodulatorPreThread::run() {
 | 
			
		||||
    std::cout << "Demodulator preprocessor thread done." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DemodulatorThreadParameters &DemodulatorPreThread::getParams() {
 | 
			
		||||
    return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorPreThread::setParams(DemodulatorThreadParameters ¶ms_in) {
 | 
			
		||||
    params = params_in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorPreThread::setDemodType(std::string demodType) {
 | 
			
		||||
    this->newDemodType = demodType;
 | 
			
		||||
    DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD);
 | 
			
		||||
    command.demodType = demodType;
 | 
			
		||||
    command.bandwidth = params.bandwidth;
 | 
			
		||||
    command.audioSampleRate = params.audioSampleRate;
 | 
			
		||||
    workerQueue->push(command);
 | 
			
		||||
    demodTypeChanged.store(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string DemodulatorPreThread::getDemodType() {
 | 
			
		||||
    if (demodTypeChanged.load()) {
 | 
			
		||||
        return newDemodType;
 | 
			
		||||
    }
 | 
			
		||||
    return demodType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemodulatorPreThread::terminate() {
 | 
			
		||||
    terminated = true;
 | 
			
		||||
    DemodulatorThreadIQData *inp = new DemodulatorThreadIQData;    // push dummy to nudge queue
 | 
			
		||||
@ -331,3 +284,12 @@ void DemodulatorPreThread::terminate() {
 | 
			
		||||
    delete workerResults;
 | 
			
		||||
    delete workerQueue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Modem *DemodulatorPreThread::getModem() {
 | 
			
		||||
    return cModem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemKit *DemodulatorPreThread::getModemKit() {
 | 
			
		||||
    return cModemKit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,35 +15,25 @@ public:
 | 
			
		||||
 | 
			
		||||
    void run();
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadParameters &getParams() {
 | 
			
		||||
        return params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setParams(DemodulatorThreadParameters ¶ms_in) {
 | 
			
		||||
        params = params_in;
 | 
			
		||||
    }
 | 
			
		||||
    DemodulatorThreadParameters &getParams();
 | 
			
		||||
    void setParams(DemodulatorThreadParameters ¶ms_in);
 | 
			
		||||
    
 | 
			
		||||
    void setDemodType(std::string demodType);
 | 
			
		||||
    std::string getDemodType();
 | 
			
		||||
 | 
			
		||||
    void initialize();
 | 
			
		||||
    void terminate();
 | 
			
		||||
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
    static void *pthread_helper(void *context) {
 | 
			
		||||
        return ((DemodulatorPreThread *) context)->threadMain();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    Modem *getModem();
 | 
			
		||||
    ModemKit *getModemKit();
 | 
			
		||||
    
 | 
			
		||||
protected:
 | 
			
		||||
    msresamp_crcf iqResampler;
 | 
			
		||||
    double iqResampleRatio;
 | 
			
		||||
    std::vector<liquid_float_complex> resampledData;
 | 
			
		||||
 | 
			
		||||
    msresamp_rrrf audioResampler;
 | 
			
		||||
    msresamp_rrrf stereoResampler;
 | 
			
		||||
    double audioResampleRatio;
 | 
			
		||||
 | 
			
		||||
    firfilt_rrrf firStereoLeft;
 | 
			
		||||
    firfilt_rrrf firStereoRight;
 | 
			
		||||
    iirfilt_crcf iirStereoPilot;
 | 
			
		||||
    Modem *cModem;
 | 
			
		||||
    ModemKit *cModemKit;
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadParameters params;
 | 
			
		||||
    DemodulatorThreadParameters lastParams;
 | 
			
		||||
@ -52,6 +42,9 @@ protected:
 | 
			
		||||
    int shiftFrequency;
 | 
			
		||||
 | 
			
		||||
    std::atomic_bool initialized;
 | 
			
		||||
    std::atomic_bool demodTypeChanged;
 | 
			
		||||
    std::string demodType;
 | 
			
		||||
    std::string newDemodType;
 | 
			
		||||
 | 
			
		||||
    DemodulatorWorkerThread *workerThread;
 | 
			
		||||
    std::thread *t_Worker;
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -5,25 +5,24 @@
 | 
			
		||||
 | 
			
		||||
#include "DemodDefs.h"
 | 
			
		||||
#include "AudioThread.h"
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
typedef ThreadQueue<AudioThreadInput *> DemodulatorThreadOutputQueue;
 | 
			
		||||
 | 
			
		||||
#define DEMOD_VIS_SIZE 2048
 | 
			
		||||
class DemodulatorInstance;
 | 
			
		||||
 | 
			
		||||
class DemodulatorThread : public IOThread {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    DemodulatorThread();
 | 
			
		||||
    DemodulatorThread(DemodulatorInstance *parent);
 | 
			
		||||
    ~DemodulatorThread();
 | 
			
		||||
 | 
			
		||||
    void onBindOutput(std::string name, ThreadQueueBase *threadQueue);
 | 
			
		||||
    
 | 
			
		||||
    void run();
 | 
			
		||||
    void terminate();
 | 
			
		||||
 | 
			
		||||
    void setStereo(bool state);
 | 
			
		||||
    bool isStereo();
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    void setAGC(bool state);
 | 
			
		||||
    bool getAGC();
 | 
			
		||||
 | 
			
		||||
@ -34,126 +33,25 @@ public:
 | 
			
		||||
    void setSquelchLevel(float signal_level_in);
 | 
			
		||||
    float getSquelchLevel();
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
        return ((DemodulatorThread *) context)->threadMain();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    DemodulatorInstance *demodInstance;
 | 
			
		||||
    ReBuffer<AudioThreadInput> outputBuffers;
 | 
			
		||||
 | 
			
		||||
    std::vector<liquid_float_complex> agcData;
 | 
			
		||||
    std::vector<float> agcAMData;
 | 
			
		||||
    std::vector<float> demodOutputData;
 | 
			
		||||
    std::vector<float> demodStereoData;
 | 
			
		||||
    std::vector<float> resampledOutputData;
 | 
			
		||||
    std::vector<float> resampledStereoData;
 | 
			
		||||
	std::vector<unsigned int> demodOutputDataDigital;
 | 
			
		||||
	//std::vector<unsigned int> demodOutputDataDigitalTest;
 | 
			
		||||
 | 
			
		||||
	//std::vector<unsigned char> demodOutputSoftbits;
 | 
			
		||||
	//std::vector<unsigned char> demodOutputSoftbitsTest;
 | 
			
		||||
 | 
			
		||||
    freqdem demodFM;
 | 
			
		||||
    ampmodem demodAM;
 | 
			
		||||
    ampmodem demodAM_DSB_CSP;
 | 
			
		||||
    ampmodem demodAM_DSB;
 | 
			
		||||
    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;
 | 
			
		||||
    float amOutputCeilMA;
 | 
			
		||||
    float amOutputCeilMAA;
 | 
			
		||||
 | 
			
		||||
    std::atomic_bool stereo;
 | 
			
		||||
    std::atomic_bool muted;
 | 
			
		||||
    std::atomic_bool agcEnabled;
 | 
			
		||||
    std::atomic_int demodulatorType;
 | 
			
		||||
    std::atomic_int demodulatorCons;
 | 
			
		||||
    int audioSampleRate;
 | 
			
		||||
 | 
			
		||||
    std::atomic<float> squelchLevel;
 | 
			
		||||
    std::atomic<float> signalLevel;
 | 
			
		||||
    bool squelchEnabled;
 | 
			
		||||
    
 | 
			
		||||
    bool currentDemodLock;
 | 
			
		||||
	int currentDemodCons;
 | 
			
		||||
 | 
			
		||||
	void updateDemodulatorCons(int Cons);
 | 
			
		||||
    void updateDemodulatorLock(modem demod, float sensitivity);
 | 
			
		||||
 | 
			
		||||
    Modem *cModem;
 | 
			
		||||
    ModemKit *cModemKit;
 | 
			
		||||
    
 | 
			
		||||
    DemodulatorThreadPostInputQueue* iqInputQueue;
 | 
			
		||||
    AudioThreadInputQueue *audioOutputQueue;
 | 
			
		||||
    DemodulatorThreadOutputQueue* audioVisOutputQueue;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(),
 | 
			
		||||
        commandQueue(NULL), resultQueue(NULL) {
 | 
			
		||||
        commandQueue(NULL), resultQueue(NULL), cModem(nullptr), cModemKit(nullptr) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DemodulatorWorkerThread::~DemodulatorWorkerThread() {
 | 
			
		||||
@ -18,7 +18,8 @@ void DemodulatorWorkerThread::run() {
 | 
			
		||||
    
 | 
			
		||||
    while (!terminated) {
 | 
			
		||||
        bool filterChanged = false;
 | 
			
		||||
        DemodulatorWorkerThreadCommand filterCommand;
 | 
			
		||||
        bool makeDemod = false;
 | 
			
		||||
        DemodulatorWorkerThreadCommand filterCommand, demodCommand;
 | 
			
		||||
        DemodulatorWorkerThreadCommand command;
 | 
			
		||||
 | 
			
		||||
        bool done = false;
 | 
			
		||||
@ -29,6 +30,10 @@ void DemodulatorWorkerThread::run() {
 | 
			
		||||
                filterChanged = true;
 | 
			
		||||
                filterCommand = command;
 | 
			
		||||
                break;
 | 
			
		||||
            case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD:
 | 
			
		||||
                makeDemod = true;
 | 
			
		||||
                demodCommand = command;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
@ -36,7 +41,7 @@ void DemodulatorWorkerThread::run() {
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        if (filterChanged && !terminated) {
 | 
			
		||||
        if ((makeDemod || filterChanged) && !terminated) {
 | 
			
		||||
            DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS);
 | 
			
		||||
 | 
			
		||||
            float As = 60.0f;         // stop-band attenuation [dB]
 | 
			
		||||
@ -46,45 +51,22 @@ void DemodulatorWorkerThread::run() {
 | 
			
		||||
                result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (filterCommand.bandwidth && filterCommand.audioSampleRate) {
 | 
			
		||||
                result.audioResamplerRatio = (double) (filterCommand.audioSampleRate) / (double) filterCommand.bandwidth;
 | 
			
		||||
                result.audioResampler = msresamp_rrrf_create(result.audioResamplerRatio, As);
 | 
			
		||||
                result.stereoResampler = msresamp_rrrf_create(result.audioResamplerRatio, As);
 | 
			
		||||
                result.audioSampleRate = filterCommand.audioSampleRate;
 | 
			
		||||
 | 
			
		||||
                // Stereo filters / shifters
 | 
			
		||||
                double firStereoCutoff = ((double) 16000 / (double) filterCommand.audioSampleRate);
 | 
			
		||||
                float ft = ((double) 1000 / (double) filterCommand.audioSampleRate);        // filter transition
 | 
			
		||||
                float mu = 0.0f;         // fractional timing offset
 | 
			
		||||
 | 
			
		||||
                if (firStereoCutoff < 0) {
 | 
			
		||||
                    firStereoCutoff = 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (firStereoCutoff > 0.5) {
 | 
			
		||||
                    firStereoCutoff = 0.5;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                unsigned int h_len = estimate_req_filter_len(ft, As);
 | 
			
		||||
                float *h = new float[h_len];
 | 
			
		||||
                liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h);
 | 
			
		||||
 | 
			
		||||
                result.firStereoLeft = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
                result.firStereoRight = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
 | 
			
		||||
                float bw = filterCommand.bandwidth;
 | 
			
		||||
                if (bw < 100000.0) {
 | 
			
		||||
                    bw = 100000.0;
 | 
			
		||||
                }
 | 
			
		||||
                // stereo pilot filter
 | 
			
		||||
                unsigned int order =   5;       // filter order
 | 
			
		||||
                float        f0    =   ((double) 19000 / bw);
 | 
			
		||||
                float        fc    =   ((double) 19500 / bw);
 | 
			
		||||
                float        Ap    =   1.0f;
 | 
			
		||||
                As    =  60.0f;
 | 
			
		||||
                
 | 
			
		||||
                result.iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As);
 | 
			
		||||
            if (makeDemod) {
 | 
			
		||||
                cModem = Modem::makeModem(demodCommand.demodType);
 | 
			
		||||
                cModemType = demodCommand.demodType;
 | 
			
		||||
            }
 | 
			
		||||
            result.modem = cModem;
 | 
			
		||||
 | 
			
		||||
            if (makeDemod && demodCommand.bandwidth && demodCommand.audioSampleRate) {
 | 
			
		||||
                if (cModem != nullptr) {
 | 
			
		||||
                    cModemKit = cModem->buildKit(demodCommand.bandwidth, demodCommand.audioSampleRate);
 | 
			
		||||
                } else {
 | 
			
		||||
                    cModemKit = nullptr;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (makeDemod) {
 | 
			
		||||
                cModemKit = nullptr;
 | 
			
		||||
            }
 | 
			
		||||
            result.modemKit = cModemKit;
 | 
			
		||||
 | 
			
		||||
            if (filterCommand.bandwidth) {
 | 
			
		||||
                result.bandwidth = filterCommand.bandwidth;
 | 
			
		||||
@ -94,6 +76,8 @@ void DemodulatorWorkerThread::run() {
 | 
			
		||||
                result.sampleRate = filterCommand.sampleRate;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            result.modemType = cModemType;
 | 
			
		||||
            
 | 
			
		||||
            resultQueue->push(result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@
 | 
			
		||||
#include "AudioThread.h"
 | 
			
		||||
#include "ThreadQueue.h"
 | 
			
		||||
#include "CubicSDRDefs.h"
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
class DemodulatorWorkerThreadResult {
 | 
			
		||||
public:
 | 
			
		||||
@ -15,8 +16,7 @@ public:
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    DemodulatorWorkerThreadResult() :
 | 
			
		||||
            cmd(DEMOD_WORKER_THREAD_RESULT_NULL), iqResampler(NULL), iqResampleRatio(0), audioResampler(NULL), stereoResampler(NULL), audioResamplerRatio(
 | 
			
		||||
                    0), firStereoLeft(NULL), firStereoRight(NULL), iirStereoPilot(NULL), sampleRate(0), bandwidth(0), audioSampleRate(0) {
 | 
			
		||||
            cmd(DEMOD_WORKER_THREAD_RESULT_NULL), iqResampler(nullptr), iqResampleRatio(0), sampleRate(0), bandwidth(0), modemKit(nullptr), modemType("") {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -29,33 +29,29 @@ public:
 | 
			
		||||
 | 
			
		||||
    msresamp_crcf iqResampler;
 | 
			
		||||
    double iqResampleRatio;
 | 
			
		||||
    msresamp_rrrf audioResampler;
 | 
			
		||||
    msresamp_rrrf stereoResampler;
 | 
			
		||||
    double audioResamplerRatio;
 | 
			
		||||
 | 
			
		||||
    firfilt_rrrf firStereoLeft;
 | 
			
		||||
    firfilt_rrrf firStereoRight;
 | 
			
		||||
    iirfilt_crcf iirStereoPilot;
 | 
			
		||||
    
 | 
			
		||||
    DemodulatorThread *demodThread;
 | 
			
		||||
 | 
			
		||||
    long long sampleRate;
 | 
			
		||||
    unsigned int bandwidth;
 | 
			
		||||
    unsigned int audioSampleRate;
 | 
			
		||||
 | 
			
		||||
    Modem *modem;
 | 
			
		||||
    ModemKit *modemKit;
 | 
			
		||||
    std::string modemType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DemodulatorWorkerThreadCommand {
 | 
			
		||||
public:
 | 
			
		||||
    enum DemodulatorThreadCommandEnum {
 | 
			
		||||
        DEMOD_WORKER_THREAD_CMD_NULL, DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS
 | 
			
		||||
        DEMOD_WORKER_THREAD_CMD_NULL, DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS, DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    DemodulatorWorkerThreadCommand() :
 | 
			
		||||
            cmd(DEMOD_WORKER_THREAD_CMD_NULL), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0) {
 | 
			
		||||
            cmd(DEMOD_WORKER_THREAD_CMD_NULL), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0), demodType("") {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DemodulatorWorkerThreadCommand(DemodulatorThreadCommandEnum cmd) :
 | 
			
		||||
            cmd(cmd), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0) {
 | 
			
		||||
            cmd(cmd), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0), demodType("") {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -65,6 +61,7 @@ public:
 | 
			
		||||
    long long sampleRate;
 | 
			
		||||
    unsigned int bandwidth;
 | 
			
		||||
    unsigned int audioSampleRate;
 | 
			
		||||
    std::string demodType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef ThreadQueue<DemodulatorWorkerThreadCommand> DemodulatorThreadWorkerCommandQueue;
 | 
			
		||||
@ -92,4 +89,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
    DemodulatorThreadWorkerCommandQueue *commandQueue;
 | 
			
		||||
    DemodulatorThreadWorkerResultQueue *resultQueue;
 | 
			
		||||
    Modem *cModem;
 | 
			
		||||
    ModemKit *cModemKit;
 | 
			
		||||
    std::string cModemType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								src/modules/modem/Modem.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/modules/modem/Modem.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
ModemFactoryList Modem::modemFactories;
 | 
			
		||||
 | 
			
		||||
void Modem::addModemFactory(Modem *factorySingle) {
 | 
			
		||||
    modemFactories[factorySingle->getName()] = factorySingle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemFactoryList Modem::getFactories() {
 | 
			
		||||
    return modemFactories;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *Modem::makeModem(std::string modemType) {
 | 
			
		||||
    if (modemFactories.find(modemType) != modemFactories.end()) {
 | 
			
		||||
        return modemFactories[modemType]->factory();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem::Modem() {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem::~Modem() {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								src/modules/modem/Modem.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/modules/modem/Modem.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "liquid/liquid.h"
 | 
			
		||||
#include "IOThread.h"
 | 
			
		||||
#include "AudioThread.h"
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
class ModemKit {
 | 
			
		||||
public:
 | 
			
		||||
    ModemKit() : sampleRate(0), audioSampleRate(0) {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    long long sampleRate;
 | 
			
		||||
    int audioSampleRate;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ModemIQData: public ReferenceCounter {
 | 
			
		||||
public:
 | 
			
		||||
    std::vector<liquid_float_complex> data;
 | 
			
		||||
    long long sampleRate;
 | 
			
		||||
    
 | 
			
		||||
    ModemIQData() : sampleRate(0) {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ~ModemIQData() {
 | 
			
		||||
        std::lock_guard < std::mutex > lock(m_mutex);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Modem;
 | 
			
		||||
typedef std::map<std::string,Modem *> ModemFactoryList;
 | 
			
		||||
 | 
			
		||||
class Modem  {
 | 
			
		||||
public:
 | 
			
		||||
    static void addModemFactory(Modem *factorySingle);
 | 
			
		||||
    static ModemFactoryList getFactories();
 | 
			
		||||
    static Modem *makeModem(std::string modemType);
 | 
			
		||||
    virtual std::string getType() = 0;
 | 
			
		||||
    virtual std::string getName() = 0;
 | 
			
		||||
    virtual Modem *factory() = 0;
 | 
			
		||||
 | 
			
		||||
    Modem();
 | 
			
		||||
    virtual ~Modem();
 | 
			
		||||
    
 | 
			
		||||
    virtual ModemKit *buildKit(long long sampleRate, int audioSampleRate) = 0;
 | 
			
		||||
    virtual void disposeKit(ModemKit *kit) = 0;
 | 
			
		||||
    virtual void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) = 0;
 | 
			
		||||
private:
 | 
			
		||||
    static ModemFactoryList modemFactories;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										91
									
								
								src/modules/modem/ModemAnalog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/modules/modem/ModemAnalog.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
ModemAnalog::ModemAnalog() : aOutputCeil(1), aOutputCeilMA(1), aOutputCeilMAA(1) {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemAnalog::getType() {
 | 
			
		||||
    return "analog";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
 | 
			
		||||
    ModemKitAnalog *akit = new ModemKitAnalog;
 | 
			
		||||
    
 | 
			
		||||
    // stop-band attenuation [dB]
 | 
			
		||||
    float As = 60.0f;
 | 
			
		||||
    
 | 
			
		||||
    akit->sampleRate = sampleRate;
 | 
			
		||||
    akit->audioSampleRate = audioSampleRate;
 | 
			
		||||
    akit->audioResampleRatio = double(audioSampleRate) / double(sampleRate);
 | 
			
		||||
    akit->audioResampler = msresamp_rrrf_create(akit->audioResampleRatio, As);
 | 
			
		||||
    
 | 
			
		||||
    return akit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAnalog::disposeKit(ModemKit *kit) {
 | 
			
		||||
    ModemKitAnalog *akit = (ModemKitAnalog *)kit;
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf_destroy(akit->audioResampler);
 | 
			
		||||
    delete akit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAnalog::initOutputBuffers(ModemKitAnalog *akit, ModemIQData *input) {
 | 
			
		||||
    bufSize = input->data.size();
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    double audio_resample_ratio = akit->audioResampleRatio;
 | 
			
		||||
    
 | 
			
		||||
    int audio_out_size = ceil((double) (bufSize) * audio_resample_ratio) + 512;
 | 
			
		||||
    
 | 
			
		||||
    if (demodOutputData.size() != bufSize) {
 | 
			
		||||
        if (demodOutputData.capacity() < bufSize) {
 | 
			
		||||
            demodOutputData.reserve(bufSize);
 | 
			
		||||
        }
 | 
			
		||||
        demodOutputData.resize(bufSize);
 | 
			
		||||
    }
 | 
			
		||||
    if (resampledOutputData.size() != audio_out_size) {
 | 
			
		||||
        if (resampledOutputData.capacity() < audio_out_size) {
 | 
			
		||||
            resampledOutputData.reserve(audio_out_size);
 | 
			
		||||
        }
 | 
			
		||||
        resampledOutputData.resize(audio_out_size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAnalog::buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audioOut, bool autoGain) {
 | 
			
		||||
    unsigned int numAudioWritten;
 | 
			
		||||
 | 
			
		||||
    if (autoGain) {
 | 
			
		||||
        aOutputCeilMA = aOutputCeilMA + (aOutputCeil - aOutputCeilMA) * 0.025;
 | 
			
		||||
        aOutputCeilMAA = aOutputCeilMAA + (aOutputCeilMA - aOutputCeilMAA) * 0.025;
 | 
			
		||||
        aOutputCeil = 0;
 | 
			
		||||
        
 | 
			
		||||
        for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
            if (demodOutputData[i] > aOutputCeil) {
 | 
			
		||||
                aOutputCeil = demodOutputData[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        float gain = 0.5 / aOutputCeilMAA;
 | 
			
		||||
        
 | 
			
		||||
        for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
            demodOutputData[i] *= gain;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf_execute(akit->audioResampler, &demodOutputData[0], demodOutputData.size(), &resampledOutputData[0], &numAudioWritten);
 | 
			
		||||
    
 | 
			
		||||
    audioOut->channels = 1;
 | 
			
		||||
    audioOut->sampleRate = akit->audioSampleRate;
 | 
			
		||||
    audioOut->data.assign(resampledOutputData.begin(), resampledOutputData.begin() + numAudioWritten);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<float> *ModemAnalog::getDemodOutputData() {
 | 
			
		||||
    return &demodOutputData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<float> *ModemAnalog::getResampledOutputData() {
 | 
			
		||||
    return &resampledOutputData;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								src/modules/modem/ModemAnalog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/modules/modem/ModemAnalog.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
class ModemKitAnalog : public ModemKit {
 | 
			
		||||
public:
 | 
			
		||||
    ModemKitAnalog() : ModemKit(), audioResampler(nullptr), audioResampleRatio(0) {
 | 
			
		||||
        
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf audioResampler;
 | 
			
		||||
    double audioResampleRatio;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ModemAnalog : public Modem {
 | 
			
		||||
public:
 | 
			
		||||
    ModemAnalog();
 | 
			
		||||
    std::string getType();
 | 
			
		||||
    ModemKit *buildKit(long long sampleRate, int audioSampleRate);
 | 
			
		||||
    void disposeKit(ModemKit *kit);
 | 
			
		||||
    void initOutputBuffers(ModemKitAnalog *akit, ModemIQData *input);
 | 
			
		||||
    void buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audioOut, bool autoGain);
 | 
			
		||||
    std::vector<float> *getDemodOutputData();
 | 
			
		||||
    std::vector<float> *getResampledOutputData();
 | 
			
		||||
protected:
 | 
			
		||||
    int bufSize;
 | 
			
		||||
    std::vector<float> demodOutputData;
 | 
			
		||||
    std::vector<float> resampledOutputData;
 | 
			
		||||
 | 
			
		||||
    float aOutputCeil;
 | 
			
		||||
    float aOutputCeilMA;
 | 
			
		||||
    float aOutputCeilMAA;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										71
									
								
								src/modules/modem/ModemDigital.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/modules/modem/ModemDigital.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
ModemDigital::ModemDigital() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemDigital::getType() {
 | 
			
		||||
    return "digital";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemKit *ModemDigital::buildKit(long long sampleRate, int audioSampleRate) {
 | 
			
		||||
    ModemKitDigital *dkit = new ModemKitDigital;
 | 
			
		||||
    
 | 
			
		||||
    dkit->sampleRate = sampleRate;
 | 
			
		||||
    dkit->audioSampleRate = audioSampleRate;
 | 
			
		||||
    
 | 
			
		||||
    return dkit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::disposeKit(ModemKit *kit) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    
 | 
			
		||||
    delete dkit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::setDemodulatorLock(bool demod_lock_in) {
 | 
			
		||||
    currentDemodLock.store(demod_lock_in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ModemDigital::getDemodulatorLock() {
 | 
			
		||||
    return currentDemodLock.load();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::setDemodulatorCons(int demod_cons_in) {
 | 
			
		||||
    demodulatorCons.store(demod_cons_in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ModemDigital::getDemodulatorCons() {
 | 
			
		||||
    return currentDemodCons.load();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::updateDemodulatorLock(modem mod, float sensitivity) {
 | 
			
		||||
    setDemodulatorLock(modem_get_demodulator_evm(mod) <= sensitivity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::digitalStart(ModemKitDigital *kit, modem mod, ModemIQData *input) {
 | 
			
		||||
    int bufSize = input->data.size();
 | 
			
		||||
    
 | 
			
		||||
    if (demodOutputDataDigital.size() != bufSize) {
 | 
			
		||||
        if (demodOutputDataDigital.capacity() < bufSize) {
 | 
			
		||||
            demodOutputDataDigital.reserve(bufSize);
 | 
			
		||||
        }
 | 
			
		||||
        demodOutputDataDigital.resize(bufSize);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (demodulatorCons.load() != currentDemodCons.load()) {
 | 
			
		||||
        updateDemodulatorCons(demodulatorCons.load());
 | 
			
		||||
        currentDemodLock.store(false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDigital::digitalFinish(ModemKitDigital *kit, modem mod) {
 | 
			
		||||
    demodOutputDataDigital.empty();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								src/modules/modem/ModemDigital.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/modules/modem/ModemDigital.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
class ModemKitDigital : public ModemKit {
 | 
			
		||||
public:
 | 
			
		||||
    ModemKitDigital() : ModemKit() {
 | 
			
		||||
        
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ModemDigital : public Modem {
 | 
			
		||||
public:
 | 
			
		||||
    ModemDigital();
 | 
			
		||||
    std::string getType();
 | 
			
		||||
    ModemKit *buildKit(long long sampleRate, int audioSampleRate);
 | 
			
		||||
    void disposeKit(ModemKit *kit);
 | 
			
		||||
    void digitalStart(ModemKitDigital *kit, modem mod, ModemIQData *input);
 | 
			
		||||
    void digitalFinish(ModemKitDigital *kit, modem mod);
 | 
			
		||||
 | 
			
		||||
    virtual void setDemodulatorLock(bool demod_lock_in);
 | 
			
		||||
    virtual int getDemodulatorLock();
 | 
			
		||||
    
 | 
			
		||||
    virtual void setDemodulatorCons(int demod_cons_in);
 | 
			
		||||
    virtual int getDemodulatorCons();
 | 
			
		||||
 | 
			
		||||
    virtual void updateDemodulatorCons(int cons);
 | 
			
		||||
    virtual void updateDemodulatorLock(modem mod, float sensitivity);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    std::vector<unsigned int> demodOutputDataDigital;
 | 
			
		||||
    std::atomic_int demodulatorCons;
 | 
			
		||||
    std::atomic_bool currentDemodLock;
 | 
			
		||||
    std::atomic_int currentDemodCons;
 | 
			
		||||
        
 | 
			
		||||
//    std::vector<unsigned int> demodOutputDataDigitalTest;    
 | 
			
		||||
//    std::vector<unsigned char> demodOutputSoftbits;
 | 
			
		||||
//    std::vector<unsigned char> demodOutputSoftbitsTest;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										30
									
								
								src/modules/modem/analog/ModemAM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/modules/modem/analog/ModemAM.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
#include "ModemAM.h"
 | 
			
		||||
 | 
			
		||||
ModemAM::ModemAM() {
 | 
			
		||||
    demodAM = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemAM::factory() {
 | 
			
		||||
    return new ModemAM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemAM::getName() {
 | 
			
		||||
    return "AM";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitAnalog *amkit = (ModemKitAnalog *)kit;
 | 
			
		||||
    
 | 
			
		||||
    initOutputBuffers(amkit,input);
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
	for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
		ampmodem_demodulate(demodAM, input->data[i], &demodOutputData[i]);
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
    buildAudioOutput(amkit,audioOut,true);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/modules/modem/analog/ModemAM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/modules/modem/analog/ModemAM.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class ModemAM : public ModemAnalog {
 | 
			
		||||
public:
 | 
			
		||||
    ModemAM();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    ampmodem demodAM;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										30
									
								
								src/modules/modem/analog/ModemDSB.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/modules/modem/analog/ModemDSB.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
#include "ModemDSB.h"
 | 
			
		||||
 | 
			
		||||
ModemDSB::ModemDSB() {
 | 
			
		||||
    demodAM_DSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemDSB::factory() {
 | 
			
		||||
    return new ModemDSB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemDSB::getName() {
 | 
			
		||||
    return "DSB";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitAnalog *amkit = (ModemKitAnalog *)kit;
 | 
			
		||||
 | 
			
		||||
    initOutputBuffers(amkit, input);
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
	for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
		ampmodem_demodulate(demodAM_DSB, input->data[i], &demodOutputData[i]);
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
    buildAudioOutput(amkit, audioOut, true);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/modules/modem/analog/ModemDSB.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/modules/modem/analog/ModemDSB.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class ModemDSB : public ModemAnalog {
 | 
			
		||||
public:
 | 
			
		||||
    ModemDSB();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    ampmodem demodAM_DSB;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										28
									
								
								src/modules/modem/analog/ModemFM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/modules/modem/analog/ModemFM.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
#include "ModemFM.h"
 | 
			
		||||
 | 
			
		||||
ModemFM::ModemFM() {
 | 
			
		||||
    demodFM = freqdem_create(0.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemFM::factory() {
 | 
			
		||||
    return new ModemFM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemFM::getName() {
 | 
			
		||||
    return "FM";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitAnalog *fmkit = (ModemKitAnalog *)kit;
 | 
			
		||||
    
 | 
			
		||||
    initOutputBuffers(fmkit, input);
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]);
 | 
			
		||||
 | 
			
		||||
    buildAudioOutput(fmkit, audioOut, false);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/modules/modem/analog/ModemFM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/modules/modem/analog/ModemFM.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class ModemFM : public ModemAnalog {
 | 
			
		||||
public:
 | 
			
		||||
    ModemFM();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 
 | 
			
		||||
    freqdem demodFM;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										186
									
								
								src/modules/modem/analog/ModemFMStereo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/modules/modem/analog/ModemFMStereo.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
			
		||||
#include "ModemFMStereo.h"
 | 
			
		||||
 | 
			
		||||
ModemFMStereo::ModemFMStereo() {
 | 
			
		||||
    demodFM = freqdem_create(0.5);
 | 
			
		||||
 | 
			
		||||
    firStereoR2C = firhilbf_create(5, 60.0f);
 | 
			
		||||
    firStereoC2R = firhilbf_create(5, 60.0f);
 | 
			
		||||
    
 | 
			
		||||
    stereoPilot = nco_crcf_create(LIQUID_VCO);
 | 
			
		||||
    nco_crcf_reset(stereoPilot);
 | 
			
		||||
    nco_crcf_pll_set_bandwidth(stereoPilot, 0.25f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemFMStereo::~ModemFMStereo() {
 | 
			
		||||
    firhilbf_destroy(firStereoR2C);
 | 
			
		||||
    firhilbf_destroy(firStereoC2R);
 | 
			
		||||
    
 | 
			
		||||
    nco_crcf_destroy(stereoPilot);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemFMStereo::getType() {
 | 
			
		||||
    return "analog";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemFMStereo::getName() {
 | 
			
		||||
    return "FMS";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemFMStereo::factory() {
 | 
			
		||||
    return new ModemFMStereo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
 | 
			
		||||
    ModemKitFMStereo *kit = new ModemKitFMStereo;
 | 
			
		||||
    
 | 
			
		||||
    kit->audioResampleRatio = double(audioSampleRate) / double(sampleRate);
 | 
			
		||||
    
 | 
			
		||||
    float As = 60.0f;         // stop-band attenuation [dB]
 | 
			
		||||
    
 | 
			
		||||
    kit->audioResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
 | 
			
		||||
    kit->stereoResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
 | 
			
		||||
    
 | 
			
		||||
    // Stereo filters / shifters
 | 
			
		||||
    double firStereoCutoff = 16000.0 / double(audioSampleRate);
 | 
			
		||||
    // filter transition
 | 
			
		||||
    float ft = 1000.0 / double(audioSampleRate);
 | 
			
		||||
    // fractional timing offset
 | 
			
		||||
    float mu = 0.0f;
 | 
			
		||||
    
 | 
			
		||||
    if (firStereoCutoff < 0) {
 | 
			
		||||
        firStereoCutoff = 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (firStereoCutoff > 0.5) {
 | 
			
		||||
        firStereoCutoff = 0.5;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    unsigned int h_len = estimate_req_filter_len(ft, As);
 | 
			
		||||
    float *h = new float[h_len];
 | 
			
		||||
    liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h);
 | 
			
		||||
    
 | 
			
		||||
    kit->firStereoLeft = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
    kit->firStereoRight = firfilt_rrrf_create(h, h_len);
 | 
			
		||||
    
 | 
			
		||||
    // stereo pilot filter
 | 
			
		||||
    float bw = sampleRate;
 | 
			
		||||
    if (bw < 100000.0) {
 | 
			
		||||
        bw = 100000.0;
 | 
			
		||||
    }
 | 
			
		||||
    unsigned int order =   5;       // filter order
 | 
			
		||||
    float        f0    =   ((double) 19000 / bw);
 | 
			
		||||
    float        fc    =   ((double) 19500 / bw);
 | 
			
		||||
    float        Ap    =   1.0f;
 | 
			
		||||
    
 | 
			
		||||
    kit->iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As);
 | 
			
		||||
    
 | 
			
		||||
    return kit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemFMStereo::disposeKit(ModemKit *kit) {
 | 
			
		||||
    ModemKitFMStereo *fmkit = (ModemKitFMStereo *)kit;
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf_destroy(fmkit->audioResampler);
 | 
			
		||||
    msresamp_rrrf_destroy(fmkit->stereoResampler);
 | 
			
		||||
    firfilt_rrrf_destroy(fmkit->firStereoLeft);
 | 
			
		||||
    firfilt_rrrf_destroy(fmkit->firStereoRight);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitFMStereo *fmkit = (ModemKitFMStereo *)kit;
 | 
			
		||||
    int bufSize = input->data.size();
 | 
			
		||||
    liquid_float_complex u, v, w, x, y;
 | 
			
		||||
    
 | 
			
		||||
    double audio_resample_ratio = fmkit->audioResampleRatio;
 | 
			
		||||
    
 | 
			
		||||
    if (demodOutputData.size() != bufSize) {
 | 
			
		||||
        if (demodOutputData.capacity() < bufSize) {
 | 
			
		||||
            demodOutputData.reserve(bufSize);
 | 
			
		||||
        }
 | 
			
		||||
        demodOutputData.resize(bufSize);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    int audio_out_size = ceil((double) (bufSize) * audio_resample_ratio) + 512;
 | 
			
		||||
    
 | 
			
		||||
    freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]);
 | 
			
		||||
    
 | 
			
		||||
    if (resampledOutputData.size() != audio_out_size) {
 | 
			
		||||
        if (resampledOutputData.capacity() < audio_out_size) {
 | 
			
		||||
            resampledOutputData.reserve(audio_out_size);
 | 
			
		||||
        }
 | 
			
		||||
        resampledOutputData.resize(audio_out_size);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    unsigned int numAudioWritten;
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf_execute(fmkit->audioResampler, &demodOutputData[0], bufSize, &resampledOutputData[0], &numAudioWritten);
 | 
			
		||||
    
 | 
			
		||||
    if (demodStereoData.size() != bufSize) {
 | 
			
		||||
        if (demodStereoData.capacity() < bufSize) {
 | 
			
		||||
            demodStereoData.reserve(bufSize);
 | 
			
		||||
        }
 | 
			
		||||
        demodStereoData.resize(bufSize);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    float phase_error = 0;
 | 
			
		||||
    
 | 
			
		||||
    for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
        // real -> complex
 | 
			
		||||
        firhilbf_r2c_execute(firStereoR2C, demodOutputData[i], &x);
 | 
			
		||||
        
 | 
			
		||||
        // 19khz pilot band-pass
 | 
			
		||||
        iirfilt_crcf_execute(fmkit->iirStereoPilot, x, &v);
 | 
			
		||||
        nco_crcf_cexpf(stereoPilot, &w);
 | 
			
		||||
        
 | 
			
		||||
        w.imag = -w.imag; // conjf(w)
 | 
			
		||||
        
 | 
			
		||||
        // multiply u = v * conjf(w)
 | 
			
		||||
        u.real = v.real * w.real - v.imag * w.imag;
 | 
			
		||||
        u.imag = v.real * w.imag + v.imag * w.real;
 | 
			
		||||
        
 | 
			
		||||
        // cargf(u)
 | 
			
		||||
        phase_error = atan2f(u.imag,u.real);
 | 
			
		||||
        
 | 
			
		||||
        // step pll
 | 
			
		||||
        nco_crcf_pll_step(stereoPilot, phase_error);
 | 
			
		||||
        nco_crcf_step(stereoPilot);
 | 
			
		||||
        
 | 
			
		||||
        // 38khz down-mix
 | 
			
		||||
        nco_crcf_mix_down(stereoPilot, x, &y);
 | 
			
		||||
        nco_crcf_mix_down(stereoPilot, y, &x);
 | 
			
		||||
        
 | 
			
		||||
        // complex -> real
 | 
			
		||||
        firhilbf_c2r_execute(firStereoC2R, x, &demodStereoData[i]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //            std::cout << "[PLL] phase error: " << phase_error;
 | 
			
		||||
    //            std::cout << " freq:" << (((nco_crcf_get_frequency(stereoPilot) / (2.0 * M_PI)) * inp->sampleRate)) << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    if (audio_out_size != resampledStereoData.size()) {
 | 
			
		||||
        if (resampledStereoData.capacity() < audio_out_size) {
 | 
			
		||||
            resampledStereoData.reserve(audio_out_size);
 | 
			
		||||
        }
 | 
			
		||||
        resampledStereoData.resize(audio_out_size);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf_execute(fmkit->stereoResampler, &demodStereoData[0], bufSize, &resampledStereoData[0], &numAudioWritten);
 | 
			
		||||
    
 | 
			
		||||
    audioOut->channels = 2;
 | 
			
		||||
    if (audioOut->data.capacity() < (numAudioWritten * 2)) {
 | 
			
		||||
        audioOut->data.reserve(numAudioWritten * 2);
 | 
			
		||||
    }
 | 
			
		||||
    audioOut->data.resize(numAudioWritten * 2);
 | 
			
		||||
    for (int i = 0; i < numAudioWritten; i++) {
 | 
			
		||||
        float l, r;
 | 
			
		||||
        
 | 
			
		||||
        firfilt_rrrf_push(fmkit->firStereoLeft, 0.568 * (resampledOutputData[i] - (resampledStereoData[i])));
 | 
			
		||||
        firfilt_rrrf_execute(fmkit->firStereoLeft, &l);
 | 
			
		||||
        
 | 
			
		||||
        firfilt_rrrf_push(fmkit->firStereoRight, 0.568 * (resampledOutputData[i] + (resampledStereoData[i])));
 | 
			
		||||
        firfilt_rrrf_execute(fmkit->firStereoRight, &r);
 | 
			
		||||
        
 | 
			
		||||
        audioOut->data[i * 2] = l;
 | 
			
		||||
        audioOut->data[i * 2 + 1] = r;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								src/modules/modem/analog/ModemFMStereo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/modules/modem/analog/ModemFMStereo.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
class ModemKitFMStereo: public ModemKit {
 | 
			
		||||
public:
 | 
			
		||||
    ModemKitFMStereo() : audioResampler(nullptr), stereoResampler(nullptr), audioResampleRatio(0), firStereoLeft(nullptr), firStereoRight(nullptr), iirStereoPilot(nullptr) {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    msresamp_rrrf audioResampler;
 | 
			
		||||
    msresamp_rrrf stereoResampler;
 | 
			
		||||
    double audioResampleRatio;
 | 
			
		||||
    
 | 
			
		||||
    firfilt_rrrf firStereoLeft;
 | 
			
		||||
    firfilt_rrrf firStereoRight;
 | 
			
		||||
    iirfilt_crcf iirStereoPilot;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ModemFMStereo : public Modem {
 | 
			
		||||
public:
 | 
			
		||||
    ModemFMStereo();
 | 
			
		||||
    ~ModemFMStereo();
 | 
			
		||||
    std::string getType();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    ModemKit *buildKit(long long sampleRate, int audioSampleRate);
 | 
			
		||||
    void disposeKit(ModemKit *kit);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    std::vector<float> demodOutputData;
 | 
			
		||||
    std::vector<float> demodStereoData;
 | 
			
		||||
    std::vector<float> resampledOutputData;
 | 
			
		||||
    std::vector<float> resampledStereoData;
 | 
			
		||||
    freqdem demodFM;
 | 
			
		||||
        
 | 
			
		||||
    firhilbf firStereoR2C;
 | 
			
		||||
    firhilbf firStereoC2R;
 | 
			
		||||
    
 | 
			
		||||
    nco_crcf stereoPilot;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										46
									
								
								src/modules/modem/analog/ModemIQ.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/modules/modem/analog/ModemIQ.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
#include "ModemIQ.h"
 | 
			
		||||
 | 
			
		||||
ModemIQ::ModemIQ() {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemIQ::factory() {
 | 
			
		||||
    return new ModemIQ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemKit *ModemIQ::buildKit(long long sampleRate, int audioSampleRate) {
 | 
			
		||||
    ModemKit *kit = new ModemKit;
 | 
			
		||||
    return kit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemIQ::getType() {
 | 
			
		||||
    return "analog";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemIQ::getName() {
 | 
			
		||||
    return "I/Q";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemIQ::disposeKit(ModemKit *kit) {
 | 
			
		||||
    delete kit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemIQ::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    int bufSize = input->data.size();
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    audioOut->channels = 2;
 | 
			
		||||
    if (audioOut->data.capacity() < (bufSize * 2)) {
 | 
			
		||||
        audioOut->data.reserve(bufSize * 2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    audioOut->data.resize(bufSize * 2);
 | 
			
		||||
    for (int i = 0; i < bufSize; i++) {
 | 
			
		||||
        audioOut->data[i * 2] = input->data[i].imag;
 | 
			
		||||
        audioOut->data[i * 2 + 1] = input->data[i].real;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/modules/modem/analog/ModemIQ.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/modules/modem/analog/ModemIQ.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
 | 
			
		||||
class ModemIQ : public Modem {
 | 
			
		||||
public:
 | 
			
		||||
    ModemIQ();
 | 
			
		||||
    std::string getType();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    ModemKit *buildKit(long long sampleRate, int audioSampleRate);
 | 
			
		||||
    void disposeKit(ModemKit *kit);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										39
									
								
								src/modules/modem/analog/ModemLSB.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/modules/modem/analog/ModemLSB.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
#include "ModemLSB.h"
 | 
			
		||||
 | 
			
		||||
ModemLSB::ModemLSB() {
 | 
			
		||||
    // half band filter used for side-band elimination
 | 
			
		||||
    ssbFilt = resamp2_crcf_create(12,-0.25f,60.0f);
 | 
			
		||||
    demodAM_LSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_LSB, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemLSB::factory() {
 | 
			
		||||
    return new ModemLSB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemLSB::getName() {
 | 
			
		||||
    return "LSB";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemLSB::~ModemLSB() {
 | 
			
		||||
    resamp2_crcf_destroy(ssbFilt);
 | 
			
		||||
    ampmodem_destroy(demodAM_LSB);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemLSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitAnalog *akit = (ModemKitAnalog *)kit;
 | 
			
		||||
    
 | 
			
		||||
    initOutputBuffers(akit,input);
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    liquid_float_complex x, y;
 | 
			
		||||
    for (int i = 0; i < bufSize; i++) { // Reject upper band
 | 
			
		||||
        resamp2_crcf_filter_execute(ssbFilt,input->data[i],&x,&y);
 | 
			
		||||
        ampmodem_demodulate(demodAM_LSB, x, &demodOutputData[i]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    buildAudioOutput(akit, audioOut, true);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/modules/modem/analog/ModemLSB.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/modules/modem/analog/ModemLSB.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Modem.h"
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class ModemLSB : public ModemAnalog {
 | 
			
		||||
public:
 | 
			
		||||
    ModemLSB();
 | 
			
		||||
    ~ModemLSB();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    resamp2_crcf ssbFilt;
 | 
			
		||||
    ampmodem demodAM_LSB;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										40
									
								
								src/modules/modem/analog/ModemUSB.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/modules/modem/analog/ModemUSB.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
#include "ModemUSB.h"
 | 
			
		||||
 | 
			
		||||
ModemUSB::ModemUSB() {
 | 
			
		||||
    // half band filter used for side-band elimination
 | 
			
		||||
    ssbFilt = resamp2_crcf_create(12,-0.25f,60.0f);
 | 
			
		||||
    demodAM_USB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_USB, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemUSB::factory() {
 | 
			
		||||
    return new ModemUSB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemUSB::getName() {
 | 
			
		||||
    return "USB";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemUSB::~ModemUSB() {
 | 
			
		||||
    resamp2_crcf_destroy(ssbFilt);
 | 
			
		||||
    ampmodem_destroy(demodAM_USB);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemUSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitAnalog *akit = (ModemKitAnalog *)kit;
 | 
			
		||||
    
 | 
			
		||||
    initOutputBuffers(akit,input);
 | 
			
		||||
    
 | 
			
		||||
    if (!bufSize) {
 | 
			
		||||
        input->decRefCount();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    liquid_float_complex x, y;
 | 
			
		||||
    for (int i = 0; i < bufSize; i++) { // Reject lower band
 | 
			
		||||
        resamp2_crcf_filter_execute(ssbFilt,input->data[i],&x,&y);
 | 
			
		||||
        ampmodem_demodulate(demodAM_USB, y, &demodOutputData[i]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    buildAudioOutput(akit, audioOut, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								src/modules/modem/analog/ModemUSB.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/modules/modem/analog/ModemUSB.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemAnalog.h"
 | 
			
		||||
 | 
			
		||||
class ModemUSB : public ModemAnalog {
 | 
			
		||||
public:
 | 
			
		||||
    ModemUSB();
 | 
			
		||||
    ~ModemUSB();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    resamp2_crcf ssbFilt;
 | 
			
		||||
    ampmodem demodAM_USB;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										89
									
								
								src/modules/modem/digital/ModemAPSK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/modules/modem/digital/ModemAPSK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
#include "ModemAPSK.h"
 | 
			
		||||
 | 
			
		||||
ModemAPSK::ModemAPSK() {
 | 
			
		||||
    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);
 | 
			
		||||
    demodulatorCons.store(4);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemAPSK::factory() {
 | 
			
		||||
    return new ModemAPSK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemAPSK::~ModemAPSK() {
 | 
			
		||||
    modem_destroy(demodAPSK4);
 | 
			
		||||
    modem_destroy(demodAPSK8);
 | 
			
		||||
    modem_destroy(demodAPSK16);
 | 
			
		||||
    modem_destroy(demodAPSK32);
 | 
			
		||||
    modem_destroy(demodAPSK64);
 | 
			
		||||
    modem_destroy(demodAPSK128);
 | 
			
		||||
    modem_destroy(demodAPSK256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemAPSK::getName() {
 | 
			
		||||
    return "APSK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAPSK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemAPSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    
 | 
			
		||||
    digitalStart(dkit, demodAPSK, input);
 | 
			
		||||
    
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodAPSK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    updateDemodulatorLock(demodAPSK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodAPSK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/modules/modem/digital/ModemAPSK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/modules/modem/digital/ModemAPSK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemAPSK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemAPSK();
 | 
			
		||||
    ~ModemAPSK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodAPSK;
 | 
			
		||||
    modem demodAPSK4;
 | 
			
		||||
    modem demodAPSK8;
 | 
			
		||||
    modem demodAPSK16;
 | 
			
		||||
    modem demodAPSK32;
 | 
			
		||||
    modem demodAPSK64;
 | 
			
		||||
    modem demodAPSK128;
 | 
			
		||||
    modem demodAPSK256;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										91
									
								
								src/modules/modem/digital/ModemASK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/modules/modem/digital/ModemASK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
#include "ModemASK.h"
 | 
			
		||||
 | 
			
		||||
ModemASK::ModemASK() {
 | 
			
		||||
    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);
 | 
			
		||||
    demodASK = demodASK2;
 | 
			
		||||
    demodulatorCons.store(2);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemASK::factory() {
 | 
			
		||||
    return new ModemASK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemASK::~ModemASK() {
 | 
			
		||||
    modem_destroy(demodASK4);
 | 
			
		||||
    modem_destroy(demodASK8);
 | 
			
		||||
    modem_destroy(demodASK16);
 | 
			
		||||
    modem_destroy(demodASK32);
 | 
			
		||||
    modem_destroy(demodASK64);
 | 
			
		||||
    modem_destroy(demodASK128);
 | 
			
		||||
    modem_destroy(demodASK256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemASK::getName() {
 | 
			
		||||
    return "ASK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemASK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
        
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemASK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    
 | 
			
		||||
    digitalStart(dkit, demodASK, input);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodASK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodASK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodASK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/modules/modem/digital/ModemASK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/modules/modem/digital/ModemASK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemASK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemASK();
 | 
			
		||||
    ~ModemASK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodASK;
 | 
			
		||||
    modem demodASK2;
 | 
			
		||||
    modem demodASK4;
 | 
			
		||||
    modem demodASK8;
 | 
			
		||||
    modem demodASK16;
 | 
			
		||||
    modem demodASK32;
 | 
			
		||||
    modem demodASK64;
 | 
			
		||||
    modem demodASK128;
 | 
			
		||||
    modem demodASK256;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										35
									
								
								src/modules/modem/digital/ModemBPSK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/modules/modem/digital/ModemBPSK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#include "ModemBPSK.h"
 | 
			
		||||
 | 
			
		||||
ModemBPSK::ModemBPSK() {
 | 
			
		||||
    demodBPSK = modem_create(LIQUID_MODEM_BPSK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemBPSK::factory() {
 | 
			
		||||
    return new ModemBPSK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemBPSK::~ModemBPSK() {
 | 
			
		||||
    modem_destroy(demodBPSK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemBPSK::getName() {
 | 
			
		||||
    return "BPSK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemBPSK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemBPSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    digitalStart(dkit, demodBPSK, input);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0, bufSize=input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodBPSK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodBPSK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodBPSK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/modules/modem/digital/ModemBPSK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/modules/modem/digital/ModemBPSK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemBPSK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemBPSK();
 | 
			
		||||
    ~ModemBPSK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodBPSK;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										91
									
								
								src/modules/modem/digital/ModemDPSK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/modules/modem/digital/ModemDPSK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
#include "ModemDPSK.h"
 | 
			
		||||
 | 
			
		||||
ModemDPSK::ModemDPSK() {
 | 
			
		||||
    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);
 | 
			
		||||
    demodulatorCons.store(2);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemDPSK::factory() {
 | 
			
		||||
    return new ModemDPSK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemDPSK::getName() {
 | 
			
		||||
    return "DPSK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemDPSK::~ModemDPSK() {
 | 
			
		||||
    modem_destroy(demodDPSK2);
 | 
			
		||||
    modem_destroy(demodDPSK4);
 | 
			
		||||
    modem_destroy(demodDPSK8);
 | 
			
		||||
    modem_destroy(demodDPSK16);
 | 
			
		||||
    modem_destroy(demodDPSK32);
 | 
			
		||||
    modem_destroy(demodDPSK64);
 | 
			
		||||
    modem_destroy(demodDPSK128);
 | 
			
		||||
    modem_destroy(demodDPSK256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDPSK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
        
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemDPSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
   
 | 
			
		||||
    digitalStart(dkit, demodDPSK, input);
 | 
			
		||||
 
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodDPSK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodDPSK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodDPSK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/modules/modem/digital/ModemDPSK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/modules/modem/digital/ModemDPSK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemDPSK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemDPSK();
 | 
			
		||||
    ~ModemDPSK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodDPSK;
 | 
			
		||||
    modem demodDPSK2;
 | 
			
		||||
    modem demodDPSK4;
 | 
			
		||||
    modem demodDPSK8;
 | 
			
		||||
    modem demodDPSK16;
 | 
			
		||||
    modem demodDPSK32;
 | 
			
		||||
    modem demodDPSK64;
 | 
			
		||||
    modem demodDPSK128;
 | 
			
		||||
    modem demodDPSK256;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								src/modules/modem/digital/ModemOOK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/modules/modem/digital/ModemOOK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#include "ModemOOK.h"
 | 
			
		||||
 | 
			
		||||
ModemOOK::ModemOOK() {
 | 
			
		||||
    demodOOK = modem_create(LIQUID_MODEM_OOK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemOOK::factory() {
 | 
			
		||||
    return new ModemOOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemOOK::~ModemOOK() {
 | 
			
		||||
    modem_destroy(demodOOK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemOOK::getName() {
 | 
			
		||||
    return "OOK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemOOK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemOOK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    digitalStart(dkit, demodOOK, input);
 | 
			
		||||
   
 | 
			
		||||
    for (int i = 0, bufSize=input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodOOK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodOOK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodOOK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/modules/modem/digital/ModemOOK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/modules/modem/digital/ModemOOK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemOOK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemOOK();
 | 
			
		||||
    ~ModemOOK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodOOK;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										91
									
								
								src/modules/modem/digital/ModemPSK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/modules/modem/digital/ModemPSK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
#include "ModemPSK.h"
 | 
			
		||||
 | 
			
		||||
ModemPSK::ModemPSK() {
 | 
			
		||||
    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);
 | 
			
		||||
    demodulatorCons.store(2);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemPSK::factory() {
 | 
			
		||||
    return new ModemPSK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemPSK::getName() {
 | 
			
		||||
    return "PSK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemPSK::~ModemPSK() {
 | 
			
		||||
    modem_destroy(demodPSK2);
 | 
			
		||||
    modem_destroy(demodPSK4);
 | 
			
		||||
    modem_destroy(demodPSK8);
 | 
			
		||||
    modem_destroy(demodPSK16);
 | 
			
		||||
    modem_destroy(demodPSK32);
 | 
			
		||||
    modem_destroy(demodPSK64);
 | 
			
		||||
    modem_destroy(demodPSK128);
 | 
			
		||||
    modem_destroy(demodPSK256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemPSK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
                
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemPSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
 | 
			
		||||
    digitalStart(dkit, demodPSK, input);
 | 
			
		||||
    
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodPSK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodPSK, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodPSK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/modules/modem/digital/ModemPSK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/modules/modem/digital/ModemPSK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemPSK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemPSK();
 | 
			
		||||
    ~ModemPSK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodPSK;
 | 
			
		||||
    modem demodPSK2;
 | 
			
		||||
    modem demodPSK4;
 | 
			
		||||
    modem demodPSK8;
 | 
			
		||||
    modem demodPSK16;
 | 
			
		||||
    modem demodPSK32;
 | 
			
		||||
    modem demodPSK64;
 | 
			
		||||
    modem demodPSK128;
 | 
			
		||||
    modem demodPSK256;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								src/modules/modem/digital/ModemQAM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/modules/modem/digital/ModemQAM.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
#include "ModemQAM.h"
 | 
			
		||||
 | 
			
		||||
ModemQAM::ModemQAM() {
 | 
			
		||||
    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);
 | 
			
		||||
    demodulatorCons.store(4);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemQAM::factory() {
 | 
			
		||||
    return new ModemQAM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemQAM::getName() {
 | 
			
		||||
    return "QAM";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemQAM::~ModemQAM() {
 | 
			
		||||
    modem_destroy(demodQAM4);
 | 
			
		||||
    modem_destroy(demodQAM8);
 | 
			
		||||
    modem_destroy(demodQAM16);
 | 
			
		||||
    modem_destroy(demodQAM32);
 | 
			
		||||
    modem_destroy(demodQAM64);
 | 
			
		||||
    modem_destroy(demodQAM128);
 | 
			
		||||
    modem_destroy(demodQAM256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemQAM::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
        
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemQAM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    digitalStart(dkit, demodQAM, input);
 | 
			
		||||
   
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodQAM, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodQAM, 0.5f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodQAM);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/modules/modem/digital/ModemQAM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/modules/modem/digital/ModemQAM.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemQAM : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemQAM();
 | 
			
		||||
    ~ModemQAM();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodQAM;
 | 
			
		||||
    modem demodQAM4;
 | 
			
		||||
    modem demodQAM8;
 | 
			
		||||
    modem demodQAM16;
 | 
			
		||||
    modem demodQAM32;
 | 
			
		||||
    modem demodQAM64;
 | 
			
		||||
    modem demodQAM128;
 | 
			
		||||
    modem demodQAM256;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								src/modules/modem/digital/ModemQPSK.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/modules/modem/digital/ModemQPSK.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#include "ModemQPSK.h"
 | 
			
		||||
 | 
			
		||||
ModemQPSK::ModemQPSK() {
 | 
			
		||||
    demodQPSK = modem_create(LIQUID_MODEM_QPSK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemQPSK::factory() {
 | 
			
		||||
    return new ModemQPSK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemQPSK::~ModemQPSK() {
 | 
			
		||||
    modem_destroy(demodQPSK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemQPSK::getName() {
 | 
			
		||||
    return "QPSK";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemQPSK::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemQPSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    digitalStart(dkit, demodQPSK, input);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodQPSK, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodQPSK, 0.8f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodQPSK);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/modules/modem/digital/ModemQPSK.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/modules/modem/digital/ModemQPSK.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemQPSK : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemQPSK();
 | 
			
		||||
    ~ModemQPSK();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodQPSK;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										79
									
								
								src/modules/modem/digital/ModemSQAM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/modules/modem/digital/ModemSQAM.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
#include "ModemSQAM.h"
 | 
			
		||||
 | 
			
		||||
ModemSQAM::ModemSQAM() {
 | 
			
		||||
    demodSQAM32 = modem_create(LIQUID_MODEM_SQAM32);
 | 
			
		||||
    demodSQAM128 = modem_create(LIQUID_MODEM_SQAM128);
 | 
			
		||||
    demodulatorCons.store(32);
 | 
			
		||||
    currentDemodCons.store(0);
 | 
			
		||||
    updateDemodulatorCons(32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemSQAM::factory() {
 | 
			
		||||
    return new ModemSQAM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemSQAM::~ModemSQAM() {
 | 
			
		||||
    modem_destroy(demodSQAM32);
 | 
			
		||||
    modem_destroy(demodSQAM128);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemSQAM::getName() {
 | 
			
		||||
    return "SQAM";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemSQAM::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
        
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemSQAM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
 | 
			
		||||
    digitalStart(dkit, demodSQAM, input);
 | 
			
		||||
    
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodSQAM, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodSQAM, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodSQAM);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/modules/modem/digital/ModemSQAM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/modules/modem/digital/ModemSQAM.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemSQAM : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemSQAM();
 | 
			
		||||
    ~ModemSQAM();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodSQAM;
 | 
			
		||||
    modem demodSQAM32;
 | 
			
		||||
    modem demodSQAM128;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										35
									
								
								src/modules/modem/digital/ModemST.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/modules/modem/digital/ModemST.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#include "ModemST.h"
 | 
			
		||||
 | 
			
		||||
ModemST::ModemST() {
 | 
			
		||||
    demodST = modem_create(LIQUID_MODEM_V29);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Modem *ModemST::factory() {
 | 
			
		||||
    return new ModemST;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModemST::getName() {
 | 
			
		||||
    return "ST";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemST::~ModemST() {
 | 
			
		||||
    modem_destroy(demodST);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemST::updateDemodulatorCons(int cons) {
 | 
			
		||||
    if (currentDemodCons.load() != cons) {
 | 
			
		||||
        currentDemodCons = cons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModemST::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
 | 
			
		||||
    ModemKitDigital *dkit = (ModemKitDigital *)kit;
 | 
			
		||||
    digitalStart(dkit, demodST, input);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0, bufSize = input->data.size(); i < bufSize; i++) {
 | 
			
		||||
        modem_demodulate(demodST, input->data[i], &demodOutputDataDigital[i]);
 | 
			
		||||
    }
 | 
			
		||||
    updateDemodulatorLock(demodST, 0.005f);
 | 
			
		||||
    
 | 
			
		||||
    digitalFinish(dkit, demodST);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/modules/modem/digital/ModemST.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/modules/modem/digital/ModemST.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "ModemDigital.h"
 | 
			
		||||
 | 
			
		||||
class ModemST : public ModemDigital {
 | 
			
		||||
public:
 | 
			
		||||
    ModemST();
 | 
			
		||||
    ~ModemST();
 | 
			
		||||
    std::string getName();
 | 
			
		||||
    Modem *factory();
 | 
			
		||||
    void updateDemodulatorCons(int cons);
 | 
			
		||||
    void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    modem demodST;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#include "FFTDataDistributor.h"
 | 
			
		||||
 | 
			
		||||
FFTDataDistributor::FFTDataDistributor() : linesPerSecond(DEFAULT_WATERFALL_LPS), lineRateAccum(0.0), fftSize(DEFAULT_FFT_SIZE) {
 | 
			
		||||
FFTDataDistributor::FFTDataDistributor() : fftSize(DEFAULT_FFT_SIZE), linesPerSecond(DEFAULT_WATERFALL_LPS), lineRateAccum(0.0) {
 | 
			
		||||
    bufferedItems = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ using namespace std;
 | 
			
		||||
 | 
			
		||||
#define STRINGIFY(A)  #A
 | 
			
		||||
 | 
			
		||||
DataElement::DataElement() : data_type(DATA_NULL), data_val(NULL), data_size(0), unit_size(0) {
 | 
			
		||||
DataElement::DataElement() : data_type(DATA_NULL), data_size(0), unit_size(0), data_val(NULL) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DataElement::~DataElement() {
 | 
			
		||||
@ -393,11 +393,11 @@ void DataElement::setSerialized(char *ser_str) {
 | 
			
		||||
 | 
			
		||||
/* DataNode class */
 | 
			
		||||
 | 
			
		||||
DataNode::DataNode(): ptr(0), parentNode(NULL) {
 | 
			
		||||
DataNode::DataNode(): parentNode(NULL), ptr(0) {
 | 
			
		||||
    data_elem = new DataElement();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DataNode::DataNode(const char *name_in): ptr(0), parentNode(NULL) {
 | 
			
		||||
DataNode::DataNode(const char *name_in): parentNode(NULL), ptr(0) {
 | 
			
		||||
    node_name = name_in;
 | 
			
		||||
    data_elem = new DataElement();
 | 
			
		||||
}
 | 
			
		||||
@ -1528,7 +1528,7 @@ bool DataTree::SaveToFileXML(const std::string& filename) {
 | 
			
		||||
 | 
			
		||||
bool DataTree::SaveToFile(const std::string& filename, bool compress, int compress_level) {
 | 
			
		||||
    long dataSize, compressedSize, headerSize;
 | 
			
		||||
    char *serialized, *hdr_serialized, *compressed;
 | 
			
		||||
    char *serialized = nullptr, *hdr_serialized = nullptr, *compressed = nullptr;
 | 
			
		||||
    DataTree dtHeader;
 | 
			
		||||
 | 
			
		||||
    dataSize = getSerialized(&serialized);
 | 
			
		||||
@ -1580,7 +1580,10 @@ bool DataTree::SaveToFile(const std::string& filename, bool compress, int compre
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DataTree::LoadFromFile(const std::string& filename) {
 | 
			
		||||
    char *compressed, *serialized, *hdr_serialized;
 | 
			
		||||
#if USE_FASTLZ
 | 
			
		||||
    char *compressed;
 | 
			
		||||
#endif
 | 
			
		||||
    char *serialized, *hdr_serialized;
 | 
			
		||||
    long dataSize, headerSize, compressedSize;
 | 
			
		||||
 | 
			
		||||
    ifstream fin(filename.c_str(), ios::binary);
 | 
			
		||||
 | 
			
		||||
@ -155,6 +155,24 @@ void ModeSelectorCanvas::addChoice(int value, std::string label) {
 | 
			
		||||
    numChoices = selections.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModeSelectorCanvas::setSelection(std::string label) {
 | 
			
		||||
    for (int i = 0; i < numChoices; i++) {
 | 
			
		||||
        if (selections[i].label == label) {
 | 
			
		||||
            currentSelection = i;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    currentSelection = -1;
 | 
			
		||||
    Refresh();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ModeSelectorCanvas::getSelectionLabel() {
 | 
			
		||||
    if (currentSelection == -1) {
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
    return selections[currentSelection].label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModeSelectorCanvas::setSelection(int value) {
 | 
			
		||||
    for (int i = 0; i < numChoices; i++) {
 | 
			
		||||
        if (selections[i].value == value) {
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,8 @@ public:
 | 
			
		||||
    void setHelpTip(std::string tip);
 | 
			
		||||
 | 
			
		||||
    void addChoice(int value, std::string label);
 | 
			
		||||
    void setSelection(std::string label);
 | 
			
		||||
    std::string getSelectionLabel();
 | 
			
		||||
    void setSelection(int value);
 | 
			
		||||
    int getSelection();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -87,7 +87,7 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, l
 | 
			
		||||
    glColor4f(color.r, color.g, color.b, 0.6);
 | 
			
		||||
 | 
			
		||||
    float ofs = ((float) demod->getBandwidth()) / (float) srate;
 | 
			
		||||
    float ofsLeft = (demod->getDemodulatorType()!=DEMOD_TYPE_USB)?ofs:0, ofsRight = (demod->getDemodulatorType()!=DEMOD_TYPE_LSB)?ofs:0;
 | 
			
		||||
    float ofsLeft = (demod->getDemodulatorType()!="USB")?ofs:0, ofsRight = (demod->getDemodulatorType()!="LSB")?ofs:0;
 | 
			
		||||
 | 
			
		||||
    float labelHeight = 20.0 / viewHeight;
 | 
			
		||||
    float hPos = -1.0 + labelHeight;
 | 
			
		||||
@ -139,9 +139,9 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, l
 | 
			
		||||
        demodLabel = std::string("[M] ") + demodLabel;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (demod->getDemodulatorType() == DEMOD_TYPE_USB) {
 | 
			
		||||
    if (demod->getDemodulatorType() == "USB") {
 | 
			
		||||
        GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER);
 | 
			
		||||
    } else if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) {
 | 
			
		||||
    } else if (demod->getDemodulatorType() == "LSB") {
 | 
			
		||||
        GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
 | 
			
		||||
    } else {
 | 
			
		||||
        GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
 | 
			
		||||
@ -172,7 +172,7 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBA4f color, long
 | 
			
		||||
    glColor4f(color.r, color.g, color.b, 0.6);
 | 
			
		||||
 | 
			
		||||
    float ofs = ((float) demod->getBandwidth()) / (float) srate;
 | 
			
		||||
    float ofsLeft = (demod->getDemodulatorType()!=DEMOD_TYPE_USB)?ofs:0, ofsRight = (demod->getDemodulatorType()!=DEMOD_TYPE_LSB)?ofs:0;
 | 
			
		||||
    float ofsLeft = (demod->getDemodulatorType()!="USB")?ofs:0, ofsRight = (demod->getDemodulatorType()!="LSB")?ofs:0;
 | 
			
		||||
 | 
			
		||||
    glBegin(GL_LINES);
 | 
			
		||||
    glVertex3f((uxPos - 0.5) * 2.0, 1.0, 0.0);
 | 
			
		||||
@ -217,69 +217,20 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBA4f color, long
 | 
			
		||||
    std::string demodStr = "";
 | 
			
		||||
    GLFont::Align demodAlign = GLFont::GLFONT_ALIGN_CENTER;
 | 
			
		||||
 | 
			
		||||
    switch (demod->getDemodulatorType()) {
 | 
			
		||||
    case DEMOD_TYPE_FM:
 | 
			
		||||
        demodStr = "FM";
 | 
			
		||||
        demodAlign = GLFont::GLFONT_ALIGN_CENTER;
 | 
			
		||||
        break;
 | 
			
		||||
    case DEMOD_TYPE_AM:
 | 
			
		||||
        demodStr = "AM";
 | 
			
		||||
        demodAlign = GLFont::GLFONT_ALIGN_CENTER;
 | 
			
		||||
        break;
 | 
			
		||||
    case DEMOD_TYPE_LSB:
 | 
			
		||||
        demodStr = "LSB";
 | 
			
		||||
    demodStr = demod->getDemodulatorType();
 | 
			
		||||
 | 
			
		||||
    demodAlign = GLFont::GLFONT_ALIGN_CENTER;
 | 
			
		||||
 | 
			
		||||
    if (demodStr == "LSB") {
 | 
			
		||||
        demodAlign = GLFont::GLFONT_ALIGN_RIGHT;
 | 
			
		||||
        uxPos -= xOfs;
 | 
			
		||||
        break;
 | 
			
		||||
    case DEMOD_TYPE_USB:
 | 
			
		||||
        demodStr = "USB";
 | 
			
		||||
    } else if (demodStr == "USB") {
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
    // advanced demodulators start here
 | 
			
		||||
 | 
			
		||||
	if (demod->getDemodulatorCons() != NULL && demod->getDemodulatorCons() > 0) {
 | 
			
		||||
	if (demod->getDemodulatorCons() > 0) {
 | 
			
		||||
		demodStr = demodStr + std::to_string(demod->getDemodulatorCons());
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
@ -306,7 +257,7 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long
 | 
			
		||||
 | 
			
		||||
    long long bw = 0;
 | 
			
		||||
 | 
			
		||||
    int last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
    std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
 | 
			
		||||
    if (!demod) {
 | 
			
		||||
        bw = wxGetApp().getDemodMgr().getLastBandwidth();
 | 
			
		||||
@ -337,12 +288,12 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long
 | 
			
		||||
        ofs = ((float) bw) / (float) srate;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (last_type != DEMOD_TYPE_USB) {
 | 
			
		||||
    if (last_type != "USB") {
 | 
			
		||||
        glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0);
 | 
			
		||||
        glVertex3f((uxPos - 0.5) * 2.0 - ofs, -1.0, 0.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (last_type != DEMOD_TYPE_LSB) {
 | 
			
		||||
    if (last_type != "LSB") {
 | 
			
		||||
        glVertex3f((uxPos - 0.5) * 2.0 + ofs, 1.0, 0.0);
 | 
			
		||||
        glVertex3f((uxPos - 0.5) * 2.0 + ofs, -1.0, 0.0);
 | 
			
		||||
    }
 | 
			
		||||
@ -359,7 +310,7 @@ void PrimaryGLContext::DrawRangeSelector(float uxPos1, float uxPos2, RGBA4f colo
 | 
			
		||||
        uxPos1=temp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
    std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
 | 
			
		||||
    glDisable(GL_TEXTURE_2D);
 | 
			
		||||
 | 
			
		||||
@ -367,14 +318,14 @@ void PrimaryGLContext::DrawRangeSelector(float uxPos1, float uxPos2, RGBA4f colo
 | 
			
		||||
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 | 
			
		||||
    glColor4f(color.r, color.g, color.b, 0.6);
 | 
			
		||||
 | 
			
		||||
    glLineWidth((last_type == DEMOD_TYPE_USB)?2.0:1.0);
 | 
			
		||||
    glLineWidth((last_type == "USB")?2.0:1.0);
 | 
			
		||||
 | 
			
		||||
    glBegin(GL_LINES);
 | 
			
		||||
    glVertex3f((uxPos1 - 0.5) * 2.0, 1.0, 0.0);
 | 
			
		||||
    glVertex3f((uxPos1 - 0.5) * 2.0, -1.0, 0.0);
 | 
			
		||||
    glEnd();
 | 
			
		||||
 | 
			
		||||
    glLineWidth((last_type == DEMOD_TYPE_LSB)?2.0:1.0);
 | 
			
		||||
    glLineWidth((last_type == "LSB")?2.0:1.0);
 | 
			
		||||
 | 
			
		||||
    glBegin(GL_LINES);
 | 
			
		||||
    glVertex3f((uxPos2 - 0.5) * 2.0, 1.0, 0.0);
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ wxEND_EVENT_TABLE()
 | 
			
		||||
 | 
			
		||||
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
 | 
			
		||||
        InteractiveCanvas(parent, attribList), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), fft_size(0), waterfall_lines(0),
 | 
			
		||||
        dragOfs(0), mouseZoom(1), zoom(1), freqMove(0.0), freqMoving(false), hoverAlpha(1.0) {
 | 
			
		||||
        dragOfs(0), mouseZoom(1), zoom(1), freqMoving(false), freqMove(0.0), hoverAlpha(1.0) {
 | 
			
		||||
 | 
			
		||||
    glContext = new PrimaryGLContext(this, &wxGetApp().GetContext(this));
 | 
			
		||||
    linesPerSecond = 30;
 | 
			
		||||
@ -253,7 +253,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
 | 
			
		||||
    long long currentCenterFreq = getCenterFrequency();
 | 
			
		||||
 | 
			
		||||
    ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme;
 | 
			
		||||
    int last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
    std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
 | 
			
		||||
 | 
			
		||||
    if (mouseTracker.mouseInView() || wxGetApp().getDemodMgr().getActiveDemodulator()) {
 | 
			
		||||
        hoverAlpha += (1.0f-hoverAlpha)*0.1f;
 | 
			
		||||
@ -277,7 +277,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
 | 
			
		||||
 | 
			
		||||
            glContext->DrawDemod(lastActiveDemodulator, isNew?currentTheme->waterfallHighlight:currentTheme->waterfallDestroy, currentCenterFreq, currentBandwidth);
 | 
			
		||||
 | 
			
		||||
            if ((last_type == DEMOD_TYPE_LSB || last_type == DEMOD_TYPE_USB) && mouseTracker.mouseDown()) {
 | 
			
		||||
            if ((last_type == "LSB" || last_type == "USB") && mouseTracker.mouseDown()) {
 | 
			
		||||
                centerPos = mouseTracker.getMouseX();
 | 
			
		||||
                glContext->DrawRangeSelector(centerPos, centerPos-width, isNew?currentTheme->waterfallNew:currentTheme->waterfallHover);
 | 
			
		||||
            } else {
 | 
			
		||||
@ -416,16 +416,6 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
 | 
			
		||||
        }
 | 
			
		||||
        activeDemod->setMuted(!activeDemod->isMuted());
 | 
			
		||||
        break;
 | 
			
		||||
    case 'S':
 | 
			
		||||
        if (!activeDemod) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (activeDemod->isStereo()) {
 | 
			
		||||
            activeDemod->setStereo(false);
 | 
			
		||||
        } else {
 | 
			
		||||
            activeDemod->setStereo(true);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 'B':
 | 
			
		||||
        if (spectrumCanvas) {
 | 
			
		||||
            spectrumCanvas->setShowDb(!spectrumCanvas->getShowDb());
 | 
			
		||||
@ -534,8 +524,8 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
 | 
			
		||||
                double maxDist = ((double)halfBw + bufferBw);
 | 
			
		||||
 | 
			
		||||
                if ((double)dist <= maxDist) {
 | 
			
		||||
                    if ((freqDiff > 0 && demod->getDemodulatorType() == DEMOD_TYPE_USB) ||
 | 
			
		||||
                            (freqDiff < 0 && demod->getDemodulatorType() == DEMOD_TYPE_LSB)) {
 | 
			
		||||
                    if ((freqDiff > 0 && demod->getDemodulatorType() == "USB") ||
 | 
			
		||||
                            (freqDiff < 0 && demod->getDemodulatorType() == "LSB")) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@ -565,12 +555,12 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
 | 
			
		||||
            if (abs(freqDiff) > (activeDemodulator->getBandwidth() / 3)) {
 | 
			
		||||
 | 
			
		||||
                if (freqDiff > 0) {
 | 
			
		||||
                    if (activeDemodulator->getDemodulatorType() != DEMOD_TYPE_USB) {
 | 
			
		||||
                    if (activeDemodulator->getDemodulatorType() != "USB") {
 | 
			
		||||
                        nextDragState = WF_DRAG_BANDWIDTH_LEFT;
 | 
			
		||||
                        SetCursor(wxCURSOR_SIZEWE);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (activeDemodulator->getDemodulatorType() != DEMOD_TYPE_LSB) {
 | 
			
		||||
                    if (activeDemodulator->getDemodulatorType() != "LSB") {
 | 
			
		||||
                        nextDragState = WF_DRAG_BANDWIDTH_RIGHT;
 | 
			
		||||
                        SetCursor(wxCURSOR_SIZEWE);
 | 
			
		||||
                    }
 | 
			
		||||
@ -578,14 +568,14 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
 | 
			
		||||
 | 
			
		||||
                mouseTracker.setVertDragLock(true);
 | 
			
		||||
                mouseTracker.setHorizDragLock(false);
 | 
			
		||||
                setStatusText("Click and drag to change demodulator bandwidth. SPACE for direct frequency input. M for mute, D to delete, S for stereo.");
 | 
			
		||||
                setStatusText("Click and drag to change demodulator bandwidth. SPACE for direct frequency input. M for mute, D to delete.");
 | 
			
		||||
            } else {
 | 
			
		||||
                SetCursor(wxCURSOR_SIZING);
 | 
			
		||||
                nextDragState = WF_DRAG_FREQUENCY;
 | 
			
		||||
 | 
			
		||||
                mouseTracker.setVertDragLock(true);
 | 
			
		||||
                mouseTracker.setHorizDragLock(false);
 | 
			
		||||
                setStatusText("Click and drag to change demodulator frequency; SPACE for direct input. M for mute, D to delete, S for stereo.");
 | 
			
		||||
                setStatusText("Click and drag to change demodulator frequency; SPACE for direct input. M for mute, D to delete.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            SetCursor(wxCURSOR_CROSS);
 | 
			
		||||
@ -671,7 +661,6 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
 | 
			
		||||
                demod->setBandwidth(mgr->getLastBandwidth());
 | 
			
		||||
                demod->setSquelchLevel(mgr->getLastSquelchLevel());
 | 
			
		||||
                demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
 | 
			
		||||
                demod->setStereo(mgr->isLastStereo());
 | 
			
		||||
                demod->setGain(mgr->getLastGain());
 | 
			
		||||
                demod->setMuted(mgr->isLastMuted());
 | 
			
		||||
 | 
			
		||||
@ -712,9 +701,9 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
 | 
			
		||||
        float width = mouseTracker.getOriginDeltaMouseX();
 | 
			
		||||
 | 
			
		||||
        float pos;
 | 
			
		||||
        int last_type = mgr->getLastDemodulatorType();
 | 
			
		||||
        std::string last_type = mgr->getLastDemodulatorType();
 | 
			
		||||
 | 
			
		||||
        if (last_type == DEMOD_TYPE_LSB || last_type == DEMOD_TYPE_USB) {
 | 
			
		||||
        if (last_type == "LSB" || last_type == "USB") {
 | 
			
		||||
            float pos1 = mouseTracker.getOriginMouseX();
 | 
			
		||||
            float pos2 = mouseTracker.getMouseX();
 | 
			
		||||
 | 
			
		||||
@ -724,7 +713,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
 | 
			
		||||
                pos2 = tmp;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pos = (last_type == DEMOD_TYPE_LSB)?pos2:pos1;
 | 
			
		||||
            pos = (last_type == "LSB")?pos2:pos1;
 | 
			
		||||
            width *= 2;
 | 
			
		||||
        } else {
 | 
			
		||||
            pos = mouseTracker.getOriginMouseX() + width / 2.0;
 | 
			
		||||
@ -759,7 +748,6 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
 | 
			
		||||
            demod->setBandwidth(bw);
 | 
			
		||||
            demod->setSquelchLevel(mgr->getLastSquelchLevel());
 | 
			
		||||
            demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
 | 
			
		||||
            demod->setStereo(mgr->isLastStereo());
 | 
			
		||||
            demod->setGain(mgr->getLastGain());
 | 
			
		||||
 | 
			
		||||
            demod->run();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user