1 // Copyright (c) Charles J. Cliffe 2 // SPDX-License-Identifier: GPL-2.0+ 3 4 #pragma once 5 6 //WX_GL_CORE_PROFILE 1 7 //WX_GL_MAJOR_VERSION 3 8 //WX_GL_MINOR_VERSION 2 9 10 #include <thread> 11 12 #include "GLExt.h" 13 #include "PrimaryGLContext.h" 14 15 #include "ThreadBlockingQueue.h" 16 #include "SoapySDRThread.h" 17 #include "SDREnumerator.h" 18 #include "SDRPostThread.h" 19 #include "AudioThread.h" 20 #include "DemodulatorMgr.h" 21 #include "AppConfig.h" 22 #include "AppFrame.h" 23 #include "FrequencyDialog.h" 24 #include "DemodLabelDialog.h" 25 #include "BookmarkMgr.h" 26 #include "SessionMgr.h" 27 28 #include "ScopeVisualProcessor.h" 29 #include "SpectrumVisualProcessor.h" 30 #include "SpectrumVisualDataThread.h" 31 #include "SDRDevices.h" 32 #include "Modem.h" 33 34 #include "ModemFM.h" 35 #include "ModemNBFM.h" 36 #include "ModemFMStereo.h" 37 #include "ModemCW.h" 38 #include "ModemAM.h" 39 #include "ModemUSB.h" 40 #include "ModemLSB.h" 41 #include "ModemDSB.h" 42 #include "ModemIQ.h" 43 44 #ifdef ENABLE_DIGITAL_LAB 45 #include "ModemAPSK.h" 46 #include "ModemASK.h" 47 #include "ModemBPSK.h" 48 #include "ModemDPSK.h" 49 #include "ModemFSK.h" 50 #include "ModemGMSK.h" 51 #include "ModemOOK.h" 52 #include "ModemPSK.h" 53 #include "ModemQAM.h" 54 #include "ModemQPSK.h" 55 #include "ModemSQAM.h" 56 #include "ModemST.h" 57 #endif 58 59 #ifdef USE_HAMLIB 60 class RigThread; 61 #endif 62 63 #include <wx/cmdline.h> 64 65 #define NUM_DEMODULATORS 1 66 67 std::string& filterChars(std::string& s, const std::string& allowed); 68 std::string frequencyToStr(long long freq); 69 long long strToFrequency(std::string freqStr); 70 71 class CubicSDR: public wxApp { 72 public: 73 CubicSDR(); 74 75 PrimaryGLContext &GetContext(wxGLCanvas *canvas); 76 wxGLContextAttrs* GetContextAttributes(); 77 78 bool OnInit() override; 79 int OnExit() override; 80 81 void OnInitCmdLine(wxCmdLineParser& parser) override; 82 bool OnCmdLineParsed(wxCmdLineParser& parser) override; 83 84 void deviceSelector(); 85 void sdrThreadNotify(SDRThread::SDRThreadState state, const std::string& message); 86 void sdrEnumThreadNotify(SDREnumerator::SDREnumState state, std::string message); 87 88 void setFrequency(long long freq); 89 long long getFrequency(); 90 91 void lockFrequency(long long freq); 92 bool isFrequencyLocked(); 93 void unlockFrequency(); 94 95 void setOffset(long long ofs); 96 long long getOffset(); 97 98 void setAntennaName(const std::string& name); 99 const std::string& getAntennaName(); 100 101 void setChannelizerType(SDRPostThreadChannelizerType chType); 102 SDRPostThreadChannelizerType getChannelizerType(); 103 104 105 void setSampleRate(long long rate_in); 106 long long getSampleRate(); 107 108 109 std::vector<SDRDeviceInfo *> *getDevices(); 110 void setDevice(SDRDeviceInfo *dev, int waitMsForTermination); 111 void stopDevice(bool store, int waitMsForTermination); 112 SDRDeviceInfo * getDevice(); 113 114 ScopeVisualProcessor *getScopeProcessor(); 115 SpectrumVisualProcessor *getSpectrumProcessor(); 116 SpectrumVisualProcessor *getDemodSpectrumProcessor(); 117 118 DemodulatorThreadOutputQueuePtr getAudioVisualQueue(); 119 DemodulatorThreadInputQueuePtr getIQVisualQueue(); 120 DemodulatorThreadInputQueuePtr getWaterfallVisualQueue(); 121 122 DemodulatorMgr &getDemodMgr(); 123 BookmarkMgr &getBookmarkMgr(); 124 SessionMgr &getSessionMgr(); 125 126 SDRPostThread *getSDRPostThread(); 127 SDRThread *getSDRThread(); 128 129 void notifyDemodulatorsChanged(); 130 131 void removeDemodulator(const DemodulatorInstancePtr& demod); 132 133 void setFrequencySnap(int snap_in); 134 int getFrequencySnap(); 135 136 AppConfig *getConfig(); 137 void saveConfig(); 138 139 void setPPM(int ppm_in); 140 int getPPM(); 141 142 void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT, const wxString& initString = ""); 143 void showLabelInput(); 144 AppFrame *getAppFrame(); 145 146 bool areDevicesReady(); 147 bool areDevicesEnumerating(); 148 bool areModulesMissing(); 149 std::string getNotification(); 150 151 void notifyMainUIOfDeviceChange(bool forceRefreshOfGains = false); 152 153 void addRemote(const std::string& remoteAddr); 154 void removeRemote(const std::string& remoteAddr); 155 156 void setDeviceSelectorClosed(); 157 void reEnumerateDevices(); 158 bool isDeviceSelectorOpen(); 159 void closeDeviceSelector(); 160 161 void setAGCMode(bool mode); 162 bool getAGCMode(); 163 164 void setGain(const std::string& name, float gain_in); 165 float getGain(const std::string& name); 166 167 void setStreamArgs(SoapySDR::Kwargs streamArgs_in); 168 void setDeviceArgs(SoapySDR::Kwargs settingArgs_in); 169 170 bool getUseLocalMod(); 171 std::string getModulePath(); 172 173 void setActiveGainEntry(std::string gainName); 174 std::string getActiveGainEntry(); 175 176 void setSoloMode(bool solo); 177 bool getSoloMode(); 178 179 bool isShuttingDown(); 180 181 #ifdef USE_HAMLIB 182 RigThread *getRigThread(); 183 void initRig(int rigModel, std::string rigPort, int rigSerialRate); 184 void stopRig(); 185 bool rigIsActive(); 186 #endif 187 188 private: 189 int FilterEvent(wxEvent& event) override; 190 191 AppFrame *appframe = nullptr; 192 AppConfig config; 193 PrimaryGLContext *m_glContext = nullptr; 194 wxGLContextAttrs *m_glContextAttributes = nullptr; 195 196 std::vector<SDRDeviceInfo *> *devs = nullptr; 197 198 DemodulatorMgr demodMgr; 199 BookmarkMgr bookmarkMgr; 200 SessionMgr sessionMgr; 201 202 std::atomic_llong frequency; 203 std::atomic_llong offset; 204 std::atomic_int ppm, snap; 205 std::atomic_llong sampleRate; 206 std::string antennaName; 207 std::atomic_bool agcMode; 208 std::atomic_bool shuttingDown; 209 210 SDRThread *sdrThread = nullptr; 211 SDREnumerator *sdrEnum = nullptr; 212 SDRPostThread *sdrPostThread = nullptr; 213 SpectrumVisualDataThread *spectrumVisualThread = nullptr; 214 SpectrumVisualDataThread *demodVisualThread = nullptr; 215 216 SDRThreadIQDataQueuePtr pipeSDRIQData; 217 DemodulatorThreadInputQueuePtr pipeIQVisualData; 218 DemodulatorThreadOutputQueuePtr pipeAudioVisualData; 219 DemodulatorThreadInputQueuePtr pipeDemodIQVisualData; 220 DemodulatorThreadInputQueuePtr pipeWaterfallIQVisualData; 221 DemodulatorThreadInputQueuePtr pipeActiveDemodIQVisualData; 222 223 ScopeVisualProcessor scopeProcessor; 224 225 SDRDevicesDialog *deviceSelectorDialog = nullptr; 226 227 SoapySDR::Kwargs streamArgs; 228 SoapySDR::Kwargs settingArgs; 229 230 std::thread *t_SDR = nullptr; 231 std::thread *t_SDREnum = nullptr; 232 std::thread *t_PostSDR = nullptr; 233 std::thread *t_SpectrumVisual = nullptr; 234 std::thread *t_DemodVisual = nullptr; 235 std::atomic_bool devicesReady; 236 std::atomic_bool devicesFailed; 237 std::atomic_bool deviceSelectorOpen; 238 std::atomic_bool sampleRateInitialized; 239 std::atomic_bool useLocalMod; 240 std::string notifyMessage; 241 std::string modulePath; 242 243 std::mutex notify_busy; 244 245 std::atomic_bool frequency_locked; 246 std::atomic_llong lock_freq; 247 FrequencyDialog::FrequencyDialogTarget fdlgTarget; 248 std::string activeGain; 249 std::atomic_bool soloMode; 250 SDRDeviceInfo *stoppedDev; 251 #ifdef USE_HAMLIB 252 RigThread* rigThread = nullptr; 253 std::thread *t_Rig = nullptr; 254 #endif 255 256 void initAudioDevices() const; 257 }; 258 259 static const wxCmdLineEntryDesc commandLineInfo [] = 260 { 261 { wxCMD_LINE_SWITCH, "h", "help", "Command line parameter help", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, 262 { wxCMD_LINE_OPTION, "c", "config", "Specify a named configuration to use, i.e. '-c ham'", wxCMD_LINE_VAL_STRING, 0 }, 263 { wxCMD_LINE_OPTION, "m", "modpath", "Load modules from suppplied path, i.e. '-m ~/SoapyMods/'", wxCMD_LINE_VAL_STRING, 0 }, 264 #ifdef BUNDLE_SOAPY_MODS 265 { wxCMD_LINE_SWITCH, "b", "bundled", "Use bundled SoapySDR modules first instead of local.", wxCMD_LINE_VAL_NONE, 0 }, 266 #endif 267 { wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0 } 268 }; 269 270 DECLARE_APP(CubicSDR) 271