Merge pull request #723 from cjcliffe/code_quality

AppFrame refactoring
This commit is contained in:
Charles J. Cliffe 2019-04-16 18:32:47 -04:00 committed by GitHub
commit 8edd8a77dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1724 additions and 1386 deletions

View File

@ -326,6 +326,7 @@ SET (cubicsdr_sources
src/IOThread.cpp src/IOThread.cpp
src/ModemProperties.cpp src/ModemProperties.cpp
src/BookmarkMgr.cpp src/BookmarkMgr.cpp
src/SessionMgr.cpp
src/sdr/SDRDeviceInfo.cpp src/sdr/SDRDeviceInfo.cpp
src/sdr/SDRPostThread.cpp src/sdr/SDRPostThread.cpp
src/sdr/SDREnumerator.cpp src/sdr/SDREnumerator.cpp
@ -433,6 +434,7 @@ SET (cubicsdr_headers
src/IOThread.h src/IOThread.h
src/ModemProperties.h src/ModemProperties.h
src/BookmarkMgr.h src/BookmarkMgr.h
src/SessionMgr.h
src/sdr/SDRDeviceInfo.h src/sdr/SDRDeviceInfo.h
src/sdr/SDRPostThread.h src/sdr/SDRPostThread.h
src/sdr/SDREnumerator.h src/sdr/SDREnumerator.h

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,292 @@
#include "DemodulatorThread.h" #include "DemodulatorThread.h"
#include <map> #include <map>
#ifdef USE_HAMLIB
class PortSelectorDialog;
#endif
// Define a new frame type
class AppFrame: public wxFrame {
public:
AppFrame();
~AppFrame();
void initDeviceParams(SDRDeviceInfo *devInfo);
FFTVisualDataThread *getWaterfallDataThread();
WaterfallCanvas *getWaterfallCanvas();
SpectrumCanvas *getSpectrumCanvas();
void notifyUpdateModemProperties();
void setMainWaterfallFFTSize(int fftSize);
void setScopeDeviceName(std::string deviceName);
int OnGlobalKeyDown(wxKeyEvent &event);
int OnGlobalKeyUp(wxKeyEvent &event);
void setWaterfallLinesPerSecond(int lps);
void setSpectrumAvgSpeed(double avg);
FrequencyDialog::FrequencyDialogTarget getFrequencyDialogTarget();
void refreshGainUI();
void setViewState(long long center_freq, int bandwidth);
void setViewState();
long long getViewCenterFreq();
int getViewBandwidth();
bool isUserDemodBusy();
BookmarkView *getBookmarkView();
void disableSave(bool state);
//call this in case the main UI is not
//the origin of device changes / sample rate by operator,
//and must be notified back to update its UI elements
//(ex: SDR Devices dialog changing the configuration)
void notifyDeviceChanged();
#ifdef _WIN32
bool canFocus();
#endif
//set tooltip to window
void setStatusText(wxWindow* window, std::string statusText);
void setStatusText(std::string statusText, int value);
#ifdef USE_HAMLIB
void setRigControlPort(std::string portName);
void dismissRigControlPortDialog();
#endif
private:
/***
* UI Elements
*/
ScopeCanvas *scopeCanvas;
SpectrumCanvas *spectrumCanvas, *demodSpectrumCanvas;
WaterfallCanvas *waterfallCanvas, *demodWaterfallCanvas;
TuningCanvas *demodTuner;
MeterCanvas *demodSignalMeter, *demodGainMeter, *spectrumAvgMeter, *waterfallSpeedMeter;
ModeSelectorCanvas *demodModeSelector, *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
GainCanvas *gainCanvas;
BookmarkView *bookmarkView;
wxSizerItem *gainSizerItem, *gainSpacerItem;
wxSplitterWindow *mainVisSplitter, *mainSplitter, *bookmarkSplitter;
wxBoxSizer *demodTray;
//Use a raw pointer here to prevent a dangling reference
DemodulatorInstance* activeDemodulator;
/***
* Menus
*/
wxMenuBar *menuBar = nullptr;
wxMenu *fileMenu = nullptr;
wxMenu *settingsMenu = nullptr;
wxMenuItem *showTipMenuItem;
wxMenuItem *iqSwapMenuItem = nullptr;
wxMenuItem *agcMenuItem = nullptr;
wxMenu *sampleRateMenu = nullptr;
wxMenu *displayMenu = nullptr;
wxMenuItem *hideBookmarksItem;
wxMenu *recordingMenu = nullptr;
//depending on context, maps the item id to wxMenuItem*,
//OR the submenu item id to its parent wxMenuItem*.
std::map<int, wxMenuItem *> sampleRateMenuItems;
std::map<int, wxMenuItem *> antennaMenuItems;
std::map<int, wxMenuItem *> settingsMenuItems;
std::map<int, wxMenuItem *> performanceMenuItems;
std::map<int, wxMenuItem *> audioSampleRateMenuItems;
std::map<int, wxMenuItem *> recordingMenuItems;
/***
* Waterfall Data Thread
*/
FFTVisualDataThread *waterfallDataThread;
std::thread *t_FFTData;
/***
* Active Settings
*/
bool saveDisabled = false;
std::string currentSessionFile;
std::string currentBookmarkFile;
SoapySDR::ArgInfoList settingArgs;
int settingsIdMax;
std::vector<long> sampleRates;
long manualSampleRate = -1;
SDRDeviceInfo *devInfo = nullptr;
std::atomic_bool deviceChanged;
ModemProperties *modemProps;
std::atomic_bool modemPropertiesUpdated;
std::vector<std::string> antennaNames;
std::string currentTXantennaName;
AboutDialog *aboutDlg = nullptr;
std::string lastToolTip;
#ifdef ENABLE_DIGITAL_LAB
ModeSelectorCanvas *demodModeSelectorAdv;
#endif
/***
* wx Events
*/
void OnMenu(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void OnIdle(wxIdleEvent& event);
void OnDoubleClickSash(wxSplitterEvent& event);
void OnUnSplit(wxSplitterEvent& event);
void OnAboutDialogClose(wxCommandEvent& event);
void OnNewWindow(wxCommandEvent& event);
/**
* Session Management
*/
void saveSession(std::string fileName);
bool loadSession(std::string fileName);
/**
* Keyboard handlers
*/
void gkNudgeLeft(DemodulatorInstancePtr demod, int snap);
void gkNudgeRight(DemodulatorInstancePtr demod, int snap);
void toggleActiveDemodRecording();
void toggleAllActiveDemodRecording();
/**
* UI init functions
*/
ModeSelectorCanvas *makeModemSelectorPanel(wxWindow *parent, const wxGLAttributes &attribList);
WaterfallCanvas *makeWaterfallCanvas(wxWindow *parent, const wxGLAttributes &attribList);
SpectrumCanvas *makeDemodSpectrumCanvas(wxWindow *parent, const wxGLAttributes &attribList);
MeterCanvas *makeSignalMeter(wxWindow *parent, const wxGLAttributes &attribList);
ModeSelectorCanvas *makeDeltaLockButton(wxWindow *parent, const wxGLAttributes &attribList);
TuningCanvas *makeModemTuner(wxWindow *parent, const wxGLAttributes &attribList);
MeterCanvas *makeModemGainMeter(wxWindow *parent, const wxGLAttributes &attribList);
ModeSelectorCanvas *makeSoloModeButton(wxWindow *parent, const wxGLAttributes &attribList);
ModeSelectorCanvas *makeModemMuteButton(wxWindow *parent, const wxGLAttributes &attribList);
ModeSelectorCanvas *makePeakHoldButton(wxWindow *parent, const wxGLAttributes &attribList);
SpectrumCanvas *makeSpectrumCanvas(wxWindow *parent, const wxGLAttributes &attribList);
MeterCanvas *makeSpectrumAvgMeter(wxWindow *parent, const wxGLAttributes &attribList);
WaterfallCanvas *makeWaterfall(wxWindow *parent, const wxGLAttributes &attribList);
MeterCanvas *makeWaterfallSpeedMeter(wxWindow *parent, const wxGLAttributes &attribList);
ScopeCanvas *makeScopeCanvas(wxPanel *parent, const wxGLAttributes &attribList);
ModeSelectorCanvas *makeModemAdvSelectorPanel(wxPanel *parent, const wxGLAttributes &attribList);
ModemProperties *makeModemProperties(wxPanel *parent);
void initConfigurationSettings();
void initMenuBar();
void initIcon();
wxMenu *makeFileMenu();
wxMenu *makeAudioSampleRateMenu();
wxMenu *makeDisplayMenu();
wxMenu *makeRecordingMenu();
void updateRecordingMenu();
wxString getSettingsLabel(const std::string& settingsName,
const std::string& settingsValue,
const std::string& settingsSuffix = "");
/**
* Menu Action Handlers
*/
//actionXXXX manage menu actions, return true if the event has been
//treated.
bool actionOnMenuAbout(wxCommandEvent& event);
bool actionOnMenuReset(wxCommandEvent& event);
bool actionOnMenuSettings(wxCommandEvent& event);
bool actionOnMenuAGC(wxCommandEvent& event);
bool actionOnMenuSampleRate(wxCommandEvent& event);
bool actionOnMenuAudioSampleRate(wxCommandEvent& event);
bool actionOnMenuDisplay(wxCommandEvent& event);
bool actionOnMenuLoadSave(wxCommandEvent& event);
bool actionOnMenuRecording(wxCommandEvent& event);
bool actionOnMenuRig(wxCommandEvent& event);
bool actionOnMenuSDRStartStop(wxCommandEvent &event);
bool actionOnMenuPerformance(wxCommandEvent &event);
bool actionOnMenuTips(wxCommandEvent &event);
bool actionOnMenuIQSwap(wxCommandEvent &event);
bool actionOnMenuFreqOffset(wxCommandEvent &event);
bool actionOnMenuDBOffset(wxCommandEvent &event);
bool actionOnMenuSDRDevices(wxCommandEvent &event);
bool actionOnMenuSetPPM(wxCommandEvent &event);
bool actionOnMenuClose(wxCommandEvent &event);
/**
* UI Activity Handlers
*/
void handleUpdateDeviceParams();
void handleTXAntennaChange();
void handleCurrentModem();
void handleModeSelector();
void handleGainMeter();
void handleDemodWaterfallSpectrum();
void handleSpectrumWaterfall();
void handleMuteButton();
void handleScopeProcessor();
void handleScopeSpectrumProcessors();
void handleModemProperties();
void handlePeakHold();
/**
* Hamlib/Rig specific
*/
#ifdef USE_HAMLIB
wxMenu *rigMenu;
wxMenuItem *rigEnableMenuItem;
wxMenuItem *rigPortMenuItem;
wxMenuItem *rigControlMenuItem;
wxMenuItem *rigFollowMenuItem;
wxMenuItem *rigCenterLockMenuItem;
wxMenuItem *rigFollowModemMenuItem;
std::map<int, wxMenuItem *> rigSerialMenuItems;
std::map<int, wxMenuItem *> rigModelMenuItems;
int rigModel;
int rigSerialRate;
long long rigSDRIF;
std::vector<int> rigSerialRates;
std::string rigPort;
int numRigs;
PortSelectorDialog *rigPortDialog;
void enableRig();
void disableRig();
wxMenu *makeRigMenu();
void handleRigMenu();
#endif
wxDECLARE_EVENT_TABLE();
};
#define wxID_RT_AUDIO_DEVICE 1000 #define wxID_RT_AUDIO_DEVICE 1000
#define wxID_SET_FREQ_OFFSET 2001 #define wxID_SET_FREQ_OFFSET 2001
#define wxID_RESET 2002 #define wxID_RESET 2002
@ -99,209 +385,3 @@
#define wxID_RIG_SERIAL_BASE 11950 #define wxID_RIG_SERIAL_BASE 11950
#define wxID_RIG_MODEL_BASE 12000 #define wxID_RIG_MODEL_BASE 12000
#endif #endif
#ifdef USE_HAMLIB
class PortSelectorDialog;
#endif
// Define a new frame type
class AppFrame: public wxFrame {
public:
AppFrame();
~AppFrame();
wxMenu *makeFileMenu();
wxMenu *makeRecordingMenu();
void updateRecordingMenu();
void initDeviceParams(SDRDeviceInfo *devInfo);
void updateDeviceParams();
void saveSession(std::string fileName);
bool loadSession(std::string fileName);
FFTVisualDataThread *getWaterfallDataThread();
void notifyUpdateModemProperties();
void setMainWaterfallFFTSize(int fftSize);
void setScopeDeviceName(std::string deviceName);
void gkNudgeLeft(DemodulatorInstancePtr demod, int snap);
void gkNudgeRight(DemodulatorInstancePtr demod, int snap);
int OnGlobalKeyDown(wxKeyEvent &event);
int OnGlobalKeyUp(wxKeyEvent &event);
void toggleActiveDemodRecording();
void toggleAllActiveDemodRecording();
void setWaterfallLinesPerSecond(int lps);
void setSpectrumAvgSpeed(double avg);
FrequencyDialog::FrequencyDialogTarget getFrequencyDialogTarget();
void refreshGainUI();
void setViewState(long long center_freq, int bandwidth);
void setViewState();
long long getViewCenterFreq();
int getViewBandwidth();
bool isUserDemodBusy();
BookmarkView *getBookmarkView();
void disableSave(bool state);
//call this in case the main UI is not
//the origin of device changes / sample rate by operator,
//and must be notified back to update its UI elements
//(ex: SDR Devices dialog changing the configuration)
void notifyDeviceChanged();
#ifdef _WIN32
bool canFocus();
#endif
//set tooltip to window
void setStatusText(wxWindow* window, std::string statusText);
void setStatusText(std::string statusText, int value);
#ifdef USE_HAMLIB
void setRigControlPort(std::string portName);
void dismissRigControlPortDialog();
#endif
private:
void OnMenu(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void OnNewWindow(wxCommandEvent& event);
void OnIdle(wxIdleEvent& event);
void OnDoubleClickSash(wxSplitterEvent& event);
void OnUnSplit(wxSplitterEvent& event);
void OnAboutDialogClose(wxCommandEvent& event);
//actionXXXX manage menu actions, return true if the event has been
//treated.
bool actionOnMenuAbout(wxCommandEvent& event);
bool actionOnMenuReset(wxCommandEvent& event);
bool actionOnMenuSettings(wxCommandEvent& event);
bool actionOnMenuAGC(wxCommandEvent& event);
bool actionOnMenuSampleRate(wxCommandEvent& event);
bool actionOnMenuAudioSampleRate(wxCommandEvent& event);
bool actionOnMenuDisplay(wxCommandEvent& event);
bool actionOnMenuLoadSave(wxCommandEvent& event);
bool actionOnMenuRecording(wxCommandEvent& event);
bool actionOnMenuRig(wxCommandEvent& event);
wxString getSettingsLabel(const std::string& settingsName,
const std::string& settingsValue,
const std::string& settingsSuffix = "");
ScopeCanvas *scopeCanvas;
SpectrumCanvas *spectrumCanvas;
WaterfallCanvas *waterfallCanvas;
ModeSelectorCanvas *demodModeSelector;
#ifdef ENABLE_DIGITAL_LAB
ModeSelectorCanvas *demodModeSelectorAdv;
#endif
SpectrumCanvas *demodSpectrumCanvas;
WaterfallCanvas *demodWaterfallCanvas;
MeterCanvas *demodSignalMeter;
MeterCanvas *demodGainMeter;
TuningCanvas *demodTuner;
// UITestCanvas *testCanvas;
MeterCanvas *spectrumAvgMeter;
MeterCanvas *waterfallSpeedMeter;
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
GainCanvas *gainCanvas;
wxSizerItem *gainSizerItem, *gainSpacerItem;
wxSplitterWindow *mainVisSplitter, *mainSplitter, *bookmarkSplitter;
wxBoxSizer *demodTray;
BookmarkView *bookmarkView;
//Use a raw pointer here to prevent a dangling reference
DemodulatorInstance* activeDemodulator;
std::vector<RtAudio::DeviceInfo> devices;
std::map<int,RtAudio::DeviceInfo> inputDevices;
std::map<int,RtAudio::DeviceInfo> outputDevices;
std::map<int, wxMenuItem *> outputDeviceMenuItems;
std::map<int, wxMenuItem *> sampleRateMenuItems;
std::map<int, wxMenuItem *> antennaMenuItems;
//depending on context, maps the item id to wxMenuItem*,
//OR the submenu item id to its parent wxMenuItem*.
std::map<int, wxMenuItem *> settingsMenuItems;
std::map<int, wxMenuItem *> performanceMenuItems;
std::map<int, wxMenuItem *> audioSampleRateMenuItems;
//
std::map<int, wxMenuItem *> recordingMenuItems;
std::map<int, wxMenuItem *> directSamplingMenuItems;
wxMenuBar *menuBar;
wxMenu *sampleRateMenu = nullptr;
wxMenu *displayMenu = nullptr;
wxMenuItem *agcMenuItem = nullptr;
wxMenuItem *iqSwapMenuItem = nullptr;
wxMenu *fileMenu = nullptr;
wxMenu *settingsMenu = nullptr;
wxMenu *recordingMenu = nullptr;
SoapySDR::ArgInfoList settingArgs;
int settingsIdMax;
std::vector<long> sampleRates;
long manualSampleRate = -1;
std::vector<std::string> antennaNames;
std::string currentTXantennaName;
std::string currentSessionFile;
std::string currentBookmarkFile;
FFTVisualDataThread *waterfallDataThread;
std::thread *t_FFTData;
SDRDeviceInfo *devInfo;
std::atomic_bool deviceChanged;
ModemProperties *modemProps;
std::atomic_bool modemPropertiesUpdated;
wxMenuItem *showTipMenuItem;
wxMenuItem *hideBookmarksItem;
bool saveDisabled;
AboutDialog *aboutDlg;
std::string lastToolTip;
#ifdef USE_HAMLIB
void enableRig();
void disableRig();
wxMenu *rigMenu;
wxMenuItem *rigEnableMenuItem;
wxMenuItem *rigPortMenuItem;
wxMenuItem *rigControlMenuItem;
wxMenuItem *rigFollowMenuItem;
wxMenuItem *rigCenterLockMenuItem;
wxMenuItem *rigFollowModemMenuItem;
std::map<int, wxMenuItem *> rigSerialMenuItems;
std::map<int, wxMenuItem *> rigModelMenuItems;
int rigModel;
int rigSerialRate;
long long rigSDRIF;
std::vector<int> rigSerialRates;
std::string rigPort;
int numRigs;
PortSelectorDialog *rigPortDialog;
#endif
wxDECLARE_EVENT_TABLE();
};

View File

@ -216,6 +216,27 @@ CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFA
*m_glContextAttributes = glSettings; *m_glContextAttributes = glSettings;
} }
void CubicSDR::initAudioDevices() const {
std::vector<RtAudio::DeviceInfo> devices;
std::map<int, RtAudio::DeviceInfo> inputDevices, outputDevices;
AudioThread::enumerateDevices(devices);
int i = 0;
for (auto devices_i = devices.begin(); devices_i != devices.end(); devices_i++) {
if (devices_i->inputChannels) {
inputDevices[i] = *devices_i;
}
if (devices_i->outputChannels) {
outputDevices[i] = *devices_i;
}
i++;
}
wxGetApp().getDemodMgr().setOutputDevices(outputDevices);
}
bool CubicSDR::OnInit() { bool CubicSDR::OnInit() {
//use the current locale most appropriate to this system, //use the current locale most appropriate to this system,
@ -298,6 +319,8 @@ bool CubicSDR::OnInit() {
devicesFailed.store(false); devicesFailed.store(false);
deviceSelectorOpen.store(false); deviceSelectorOpen.store(false);
initAudioDevices();
// Visual Data // Visual Data
spectrumVisualThread = new SpectrumVisualDataThread(); spectrumVisualThread = new SpectrumVisualDataThread();
@ -841,12 +864,16 @@ DemodulatorThreadInputQueuePtr CubicSDR::getWaterfallVisualQueue() {
return pipeWaterfallIQVisualData; return pipeWaterfallIQVisualData;
} }
BookmarkMgr &CubicSDR::getBookmarkMgr() {
return bookmarkMgr;
}
DemodulatorMgr &CubicSDR::getDemodMgr() { DemodulatorMgr &CubicSDR::getDemodMgr() {
return demodMgr; return demodMgr;
} }
BookmarkMgr &CubicSDR::getBookmarkMgr() { SessionMgr &CubicSDR::getSessionMgr() {
return bookmarkMgr; return sessionMgr;
} }
SDRPostThread *CubicSDR::getSDRPostThread() { SDRPostThread *CubicSDR::getSDRPostThread() {
@ -917,7 +944,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
switch (targetMode) { switch (targetMode) {
case FrequencyDialog::FDIALOG_TARGET_DEFAULT: case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
case FrequencyDialog::FDIALOG_TARGET_FREQ: case FrequencyDialog::FDIALOG_TARGET_FREQ:
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle; title = demodMgr.getActiveContextModem()?demodTitle:freqTitle;
break; break;
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH: case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
title = bwTitle; title = bwTitle;
@ -938,13 +965,13 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
break; break;
} }
FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(350, 75), wxDEFAULT_DIALOG_STYLE, targetMode, initString); FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveContextModem(), wxPoint(-100,-100), wxSize(350, 75), wxDEFAULT_DIALOG_STYLE, targetMode, initString);
fdialog.ShowModal(); fdialog.ShowModal();
} }
void CubicSDR::showLabelInput() { void CubicSDR::showLabelInput() {
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator(); DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
if (activeDemod != nullptr) { if (activeDemod != nullptr) {

View File

@ -23,6 +23,7 @@
#include "FrequencyDialog.h" #include "FrequencyDialog.h"
#include "DemodLabelDialog.h" #include "DemodLabelDialog.h"
#include "BookmarkMgr.h" #include "BookmarkMgr.h"
#include "SessionMgr.h"
#include "ScopeVisualProcessor.h" #include "ScopeVisualProcessor.h"
#include "SpectrumVisualProcessor.h" #include "SpectrumVisualProcessor.h"
@ -119,6 +120,7 @@ public:
DemodulatorMgr &getDemodMgr(); DemodulatorMgr &getDemodMgr();
BookmarkMgr &getBookmarkMgr(); BookmarkMgr &getBookmarkMgr();
SessionMgr &getSessionMgr();
SDRPostThread *getSDRPostThread(); SDRPostThread *getSDRPostThread();
SDRThread *getSDRThread(); SDRThread *getSDRThread();
@ -194,6 +196,7 @@ private:
DemodulatorMgr demodMgr; DemodulatorMgr demodMgr;
BookmarkMgr bookmarkMgr; BookmarkMgr bookmarkMgr;
SessionMgr sessionMgr;
std::atomic_llong frequency; std::atomic_llong frequency;
std::atomic_llong offset; std::atomic_llong offset;
@ -248,6 +251,8 @@ private:
RigThread* rigThread = nullptr; RigThread* rigThread = nullptr;
std::thread *t_Rig = nullptr; std::thread *t_Rig = nullptr;
#endif #endif
void initAudioDevices() const;
}; };
static const wxCmdLineEntryDesc commandLineInfo [] = static const wxCmdLineEntryDesc commandLineInfo [] =

195
src/SessionMgr.cpp Normal file
View File

@ -0,0 +1,195 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "SessionMgr.h"
#include "CubicSDR.h"
void SessionMgr::saveSession(std::string fileName) {
DataTree s("cubicsdr_session");
DataNode *header = s.rootNode()->newChild("header");
//save as wstring to prevent problems
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
*header->newChild("center_freq") = wxGetApp().getFrequency();
*header->newChild("sample_rate") = wxGetApp().getSampleRate();
*header->newChild("solo_mode") = wxGetApp().getSoloMode()?1:0;
WaterfallCanvas *waterfallCanvas = wxGetApp().getAppFrame()->getWaterfallCanvas();
if (waterfallCanvas->getViewState()) {
DataNode *viewState = header->newChild("view_state");
*viewState->newChild("center_freq") = waterfallCanvas->getCenterFrequency();
*viewState->newChild("bandwidth") = waterfallCanvas->getBandwidth();
}
DataNode *demods = s.rootNode()->newChild("demodulators");
//make a local copy snapshot of the list
std::vector<DemodulatorInstancePtr> instances = wxGetApp().getDemodMgr().getDemodulators();
for (const auto &instance : instances) {
DataNode *demod = demods->newChild("demodulator");
wxGetApp().getDemodMgr().saveInstance(demod, instance);
} //end for demodulators
// Make sure the file name actually ends in .xml
std::string lcFileName = fileName;
std::transform(lcFileName.begin(), lcFileName.end(), lcFileName.begin(), ::tolower);
if (lcFileName.find_last_of(".xml") != lcFileName.length()-1) {
fileName.append(".xml");
}
s.SaveToFileXML(fileName);
}
bool SessionMgr::loadSession(std::string fileName) {
DataTree l;
if (!l.LoadFromFileXML(fileName)) {
return false;
}
//Check if it is a session file, read the root node.
if (l.rootNode()->getName() != "cubicsdr_session") {
return false;
}
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr, false);
wxGetApp().getDemodMgr().terminateAll();
WaterfallCanvas *waterfallCanvas = wxGetApp().getAppFrame()->getWaterfallCanvas();
SpectrumCanvas *spectrumCanvas = wxGetApp().getAppFrame()->getSpectrumCanvas();
try {
if (!l.rootNode()->hasAnother("header")) {
return false;
}
DataNode *header = l.rootNode()->getNext("header");
if (header->hasAnother("version")) {
//"Force" the retreiving of the value as string, even if its look like a number internally ! (ex: "0.2.0")
DataNode *versionNode = header->getNext("version");
std::wstring version;
try {
versionNode->element()->get(version);
std::cout << "Loading session file version: '" << version << "'..." << std::endl;
}
catch (DataTypeMismatchException &e) {
//this is for managing the old session format NOT encoded as std:wstring,
//force current version
std::cout << "Warning while Loading session file version, probably old format :'" << e.what() << "' please consider re-saving the current session..." << std::endl << std::flush;
version = wxString(CUBICSDR_VERSION).ToStdWstring();
}
}
if (header->hasAnother("sample_rate")) {
long sample_rate = *header->getNext("sample_rate");
SDRDeviceInfo *dev = wxGetApp().getSDRThread()->getDevice();
if (dev) {
//retreive the available sample rates. A valid previously chosen manual
//value is constrained within these limits. If it doesn't behave, lets the device choose
//for us.
long minRate = MANUAL_SAMPLE_RATE_MIN;
long maxRate = MANUAL_SAMPLE_RATE_MAX;
std::vector<long> sampleRates = dev->getSampleRates(SOAPY_SDR_RX, 0);
if (!sampleRates.empty()) {
minRate = sampleRates.front();
maxRate = sampleRates.back();
}
//If it is beyond limits, make device choose a reasonable value
if (sample_rate < minRate || sample_rate > maxRate) {
sample_rate = dev->getSampleRateNear(SOAPY_SDR_RX, 0, sample_rate);
}
//update applied value
wxGetApp().setSampleRate(sample_rate);
} else {
wxGetApp().setSampleRate(sample_rate);
}
}
if (header->hasAnother("solo_mode")) {
int solo_mode_activated = *header->getNext("solo_mode");
wxGetApp().setSoloMode(solo_mode_activated > 0);
}
else {
wxGetApp().setSoloMode(false);
}
DemodulatorInstancePtr loadedActiveDemod = nullptr;
DemodulatorInstancePtr newDemod = nullptr;
if (l.rootNode()->hasAnother("demodulators")) {
DataNode *demodulators = l.rootNode()->getNext("demodulators");
std::vector<DemodulatorInstancePtr> demodsLoaded;
while (demodulators->hasAnother("demodulator")) {
DataNode *demod = demodulators->getNext("demodulator");
if (!demod->hasAnother("bandwidth") || !demod->hasAnother("frequency")) {
continue;
}
newDemod = wxGetApp().getDemodMgr().loadInstance(demod);
if (demod->hasAnother("active")) {
loadedActiveDemod = newDemod;
}
newDemod->run();
newDemod->setActive(true);
demodsLoaded.push_back(newDemod);
}
if (!demodsLoaded.empty()) {
wxGetApp().notifyDemodulatorsChanged();
}
} // if l.rootNode()->hasAnother("demodulators")
if (header->hasAnother("center_freq")) {
long long center_freq = *header->getNext("center_freq");
wxGetApp().setFrequency(center_freq);
// std::cout << "\tCenter Frequency: " << center_freq << std::endl;
}
if (header->hasAnother("view_state")) {
DataNode *viewState = header->getNext("view_state");
if (viewState->hasAnother("center_freq") && viewState->hasAnother("bandwidth")) {
long long center_freq = *viewState->getNext("center_freq");
int bandwidth = *viewState->getNext("bandwidth");
spectrumCanvas->setView(center_freq, bandwidth);
waterfallCanvas->setView(center_freq, bandwidth);
}
} else {
spectrumCanvas->disableView();
waterfallCanvas->disableView();
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
}
if (loadedActiveDemod || newDemod) {
wxGetApp().getDemodMgr().setActiveDemodulator(loadedActiveDemod?loadedActiveDemod:newDemod, false);
}
} catch (DataTypeMismatchException &e) {
std::cout << e.what() << std::endl;
return false;
}
return true;
}

14
src/SessionMgr.h Normal file
View File

@ -0,0 +1,14 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#include "DataTree.h"
#include "AppFrame.h"
class SessionMgr {
public:
void saveSession(std::string fileName);
bool loadSession(std::string fileName);
};

View File

@ -469,7 +469,8 @@ void DemodulatorInstance::setFrequency(long long freq) {
} }
#endif #endif
#if USE_HAMLIB #if USE_HAMLIB
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && wxGetApp().getDemodMgr().getLastActiveDemodulator().get() == this) { if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() &&
wxGetApp().getDemodMgr().getCurrentModem().get() == this) {
wxGetApp().getRigThread()->setFrequency(freq,true); wxGetApp().getRigThread()->setFrequency(freq,true);
} }
#endif #endif

View File

@ -97,7 +97,7 @@ std::vector<DemodulatorInstancePtr> DemodulatorMgr::getOrderedDemodulators(bool
DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstancePtr demod, bool actives) { DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstancePtr demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) { if (!getCurrentModem()) {
return nullptr; return nullptr;
} }
auto demods_ordered = getOrderedDemodulators(actives); auto demods_ordered = getOrderedDemodulators(actives);
@ -114,7 +114,7 @@ DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstanc
DemodulatorInstancePtr DemodulatorMgr::getNextDemodulator(DemodulatorInstancePtr demod, bool actives) { DemodulatorInstancePtr DemodulatorMgr::getNextDemodulator(DemodulatorInstancePtr demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) { if (!getCurrentModem()) {
return nullptr; return nullptr;
} }
auto demods_ordered = getOrderedDemodulators(actives); auto demods_ordered = getOrderedDemodulators(actives);
@ -152,11 +152,11 @@ void DemodulatorMgr::deleteThread(DemodulatorInstancePtr demod) {
auto i = std::find(demods.begin(), demods.end(), demod); auto i = std::find(demods.begin(), demods.end(), demod);
if (activeDemodulator == demod) { if (activeContextModem == demod) {
activeDemodulator = nullptr; activeContextModem = nullptr;
} }
if (lastActiveDemodulator == demod) { if (currentModem == demod) {
lastActiveDemodulator = nullptr; currentModem = nullptr;
} }
if (activeVisualDemodulator == demod) { if (activeVisualDemodulator == demod) {
activeVisualDemodulator = nullptr; activeVisualDemodulator = nullptr;
@ -218,22 +218,27 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool tem
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
// Should this be made the current modem (i.e. clicked, toggled)
if (!temporary) { if (!temporary) {
if (activeDemodulator != nullptr) { if (activeContextModem != nullptr) {
lastActiveDemodulator = activeDemodulator; currentModem = activeContextModem;
updateLastState(); updateLastState();
} else { } else {
lastActiveDemodulator = demod; currentModem = demod;
}
updateLastState();
#if USE_HAMLIB
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && lastActiveDemodulator) {
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator->getFrequency(),true);
}
#endif
wxGetApp().getBookmarkMgr().updateActiveList();
} }
updateLastState();
wxGetApp().getBookmarkMgr().updateActiveList();
#if USE_HAMLIB
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && currentModem) {
wxGetApp().getRigThread()->setFrequency(currentModem->getFrequency(),true);
}
#endif
}
// TODO: This is probably unnecessary and confusing
if (activeVisualDemodulator) { if (activeVisualDemodulator) {
activeVisualDemodulator->setVisualOutputQueue(nullptr); activeVisualDemodulator->setVisualOutputQueue(nullptr);
} }
@ -241,15 +246,15 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool tem
demod->setVisualOutputQueue(wxGetApp().getAudioVisualQueue()); demod->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
activeVisualDemodulator = demod; activeVisualDemodulator = demod;
} else { } else {
DemodulatorInstancePtr last = getLastActiveDemodulator(); DemodulatorInstancePtr last = getCurrentModem();
if (last) { if (last) {
last->setVisualOutputQueue(wxGetApp().getAudioVisualQueue()); last->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
} }
activeVisualDemodulator = last; activeVisualDemodulator = last;
} }
// :ODOT
activeDemodulator = demod; activeContextModem = demod;
} }
//Dangerous: this is only intended by some internal classes //Dangerous: this is only intended by some internal classes
@ -266,17 +271,27 @@ void DemodulatorMgr::setActiveDemodulatorByRawPointer(DemodulatorInstance* demod
} }
} }
DemodulatorInstancePtr DemodulatorMgr::getActiveDemodulator() { /**
* Get the currently focused modem, i.e. the one hovered by interaction
* If no active context modem is available the current modem is returned
* @return Active Context Modem
*/
DemodulatorInstancePtr DemodulatorMgr::getActiveContextModem() {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (activeDemodulator && !activeDemodulator->isActive()) { if (activeContextModem && !activeContextModem->isActive()) {
activeDemodulator = getLastActiveDemodulator(); activeContextModem = getCurrentModem();
} }
return activeDemodulator; return activeContextModem;
} }
DemodulatorInstancePtr DemodulatorMgr::getLastActiveDemodulator() { /**
return lastActiveDemodulator; * Get the last selected / focused modem
* This is the currently active modem
* @return Current Modem
*/
DemodulatorInstancePtr DemodulatorMgr::getCurrentModem() {
return currentModem;
} }
DemodulatorInstancePtr DemodulatorMgr::getLastDemodulatorWith(const std::string& type, DemodulatorInstancePtr DemodulatorMgr::getLastDemodulatorWith(const std::string& type,
@ -304,27 +319,27 @@ DemodulatorInstancePtr DemodulatorMgr::getLastDemodulatorWith(const std::string&
void DemodulatorMgr::updateLastState() { void DemodulatorMgr::updateLastState() {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) { if (std::find(demods.begin(), demods.end(), currentModem) == demods.end()) {
if (activeDemodulator && activeDemodulator->isActive()) { if (activeContextModem && activeContextModem->isActive()) {
lastActiveDemodulator = activeDemodulator; currentModem = activeContextModem;
} else if (activeDemodulator && !activeDemodulator->isActive()){ } else if (activeContextModem && !activeContextModem->isActive()){
activeDemodulator = nullptr; activeContextModem = nullptr;
lastActiveDemodulator = nullptr; currentModem = nullptr;
} }
} }
if (lastActiveDemodulator && !lastActiveDemodulator->isActive()) { if (currentModem && !currentModem->isActive()) {
lastActiveDemodulator = nullptr; currentModem = nullptr;
} }
if (lastActiveDemodulator) { if (currentModem) {
lastBandwidth = lastActiveDemodulator->getBandwidth(); lastBandwidth = currentModem->getBandwidth();
lastDemodType = lastActiveDemodulator->getDemodulatorType(); lastDemodType = currentModem->getDemodulatorType();
lastDemodLock = lastActiveDemodulator->getDemodulatorLock()?true:false; lastDemodLock = currentModem->getDemodulatorLock()?true:false;
lastSquelchEnabled = lastActiveDemodulator->isSquelchEnabled(); lastSquelchEnabled = currentModem->isSquelchEnabled();
lastSquelch = lastActiveDemodulator->getSquelchLevel(); lastSquelch = currentModem->getSquelchLevel();
lastGain = lastActiveDemodulator->getGain(); lastGain = currentModem->getGain();
lastModemSettings[lastDemodType] = lastActiveDemodulator->readModemSettings(); lastModemSettings[lastDemodType] = currentModem->readModemSettings();
} }
} }
@ -403,6 +418,10 @@ void DemodulatorMgr::setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs) {
outputDevices = devs; outputDevices = devs;
} }
std::map<int, RtAudio::DeviceInfo> DemodulatorMgr::getOutputDevices() {
return outputDevices;
}
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstancePtr inst) { void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstancePtr inst) {
*node->newChild("bandwidth") = inst->getBandwidth(); *node->newChild("bandwidth") = inst->getBandwidth();
@ -420,7 +439,7 @@ void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstancePtr inst) {
*node->newChild("delta_lock") = inst->isDeltaLock() ? 1 : 0; *node->newChild("delta_lock") = inst->isDeltaLock() ? 1 : 0;
*node->newChild("delta_ofs") = inst->getDeltaLockOfs(); *node->newChild("delta_ofs") = inst->getDeltaLockOfs();
} }
if (inst == getLastActiveDemodulator()) { if (inst == getCurrentModem()) {
*node->newChild("active") = 1; *node->newChild("active") = 1;
} }

View File

@ -39,8 +39,8 @@ public:
// and only set a pre-existing demod // and only set a pre-existing demod
void setActiveDemodulatorByRawPointer(DemodulatorInstance* demod, bool temporary = true); void setActiveDemodulatorByRawPointer(DemodulatorInstance* demod, bool temporary = true);
DemodulatorInstancePtr getActiveDemodulator(); DemodulatorInstancePtr getActiveContextModem();
DemodulatorInstancePtr getLastActiveDemodulator(); DemodulatorInstancePtr getCurrentModem();
DemodulatorInstancePtr getLastDemodulatorWith(const std::string& type, DemodulatorInstancePtr getLastDemodulatorWith(const std::string& type,
const std::wstring& userLabel, const std::wstring& userLabel,
long long frequency, long long frequency,
@ -73,6 +73,7 @@ public:
void updateLastState(); void updateLastState();
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs); void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
std::map<int, RtAudio::DeviceInfo> getOutputDevices();
void saveInstance(DataNode *node, DemodulatorInstancePtr inst); void saveInstance(DataNode *node, DemodulatorInstancePtr inst);
DemodulatorInstancePtr loadInstance(DataNode *node); DemodulatorInstancePtr loadInstance(DataNode *node);
@ -86,8 +87,8 @@ private:
std::vector<DemodulatorInstancePtr> demods; std::vector<DemodulatorInstancePtr> demods;
DemodulatorInstancePtr activeDemodulator; DemodulatorInstancePtr activeContextModem;
DemodulatorInstancePtr lastActiveDemodulator; DemodulatorInstancePtr currentModem;
DemodulatorInstancePtr activeVisualDemodulator; DemodulatorInstancePtr activeVisualDemodulator;
int lastBandwidth; int lastBandwidth;

View File

@ -322,7 +322,8 @@ void DemodulatorThread::run() {
} }
if (!squelched && ati != nullptr) { if (!squelched && ati != nullptr) {
if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator().get()))) { if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance ==
wxGetApp().getDemodMgr().getCurrentModem().get()))) {
//non-blocking push needed for audio out //non-blocking push needed for audio out
if (!audioOutputQueue->try_push(ati)) { if (!audioOutputQueue->try_push(ati)) {

View File

@ -356,7 +356,7 @@ wxTreeItemId BookmarkView::refreshBookmarks() {
void BookmarkView::doUpdateActiveList() { void BookmarkView::doUpdateActiveList() {
auto demods = wxGetApp().getDemodMgr().getDemodulators(); auto demods = wxGetApp().getDemodMgr().getDemodulators();
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto lastActiveDemodulator = wxGetApp().getDemodMgr().getCurrentModem();
//capture the previously selected item info BY COPY (because the original will be destroyed together with the destroyed tree items) to restore it again after //capture the previously selected item info BY COPY (because the original will be destroyed together with the destroyed tree items) to restore it again after
//having rebuilding the whole tree. //having rebuilding the whole tree.

View File

@ -73,8 +73,8 @@ void RigThread::run() {
while (!stopping) { while (!stopping) {
std::this_thread::sleep_for(std::chrono::milliseconds(150)); std::this_thread::sleep_for(std::chrono::milliseconds(150));
auto activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator(); auto activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
auto lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto lastDemod = wxGetApp().getDemodMgr().getCurrentModem();
if (freqChanged.load() && (controlMode.load() || setOneShot.load())) { if (freqChanged.load() && (controlMode.load() || setOneShot.load())) {
status = rig_get_freq(rig, RIG_VFO_CURR, &freq); status = rig_get_freq(rig, RIG_VFO_CURR, &freq);

View File

@ -69,7 +69,7 @@ void SDRPostThread::updateActiveDemodulators() {
if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) { if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
// deactivate if active // deactivate if active
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == demod) { if (wxGetApp().getDemodMgr().getCurrentModem() == demod) {
demod->setActive(false); demod->setActive(false);
} }
@ -84,7 +84,7 @@ void SDRPostThread::updateActiveDemodulators() {
} }
} else if (!demod->isActive()) { // in range, activate if not activated } else if (!demod->isActive()) { // in range, activate if not activated
demod->setActive(true); demod->setActive(true);
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr) { if (wxGetApp().getDemodMgr().getCurrentModem() == nullptr) {
wxGetApp().getDemodMgr().setActiveDemodulator(demod); wxGetApp().getDemodMgr().setActiveDemodulator(demod);
} }
@ -305,7 +305,7 @@ void SDRPostThread::runSingleCH(SDRThreadIQData *data_in) {
// Handle active channels, channel 0 offset correction, de-interlacing and push data to demodulators // Handle active channels, channel 0 offset correction, de-interlacing and push data to demodulators
void SDRPostThread::runDemodChannels(int channelBandwidth) { void SDRPostThread::runDemodChannels(int channelBandwidth) {
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
// Calculate channel data size // Calculate channel data size
size_t chanDataSize = dataOut.size()/numChannels; size_t chanDataSize = dataOut.size()/numChannels;

View File

@ -108,7 +108,7 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstancePtr demod, RGBA4f color,
bool soloMode = wxGetApp().getSoloMode(); bool soloMode = wxGetApp().getSoloMode();
bool isRecording = demod->isRecording(); bool isRecording = demod->isRecording();
bool isSolo = soloMode && demod == wxGetApp().getDemodMgr().getLastActiveDemodulator(); bool isSolo = soloMode && demod == wxGetApp().getDemodMgr().getCurrentModem();
RGBA4f labelBg(0, 0, 0, 0.35f); RGBA4f labelBg(0, 0, 0, 0.35f);
@ -433,7 +433,7 @@ void PrimaryGLContext::drawSingleDemodLabel(const std::wstring& demodStr, float
void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long long /* center_freq */, long long srate) { void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long long /* center_freq */, long long srate) {
DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getCurrentModem();
long long bw = 0; long long bw = 0;

View File

@ -91,7 +91,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glLoadIdentity(); glLoadIdentity();
auto demods = wxGetApp().getDemodMgr().getDemodulators(); auto demods = wxGetApp().getDemodMgr().getDemodulators();
auto activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator(); auto activeDemodulator = wxGetApp().getDemodMgr().getActiveContextModem();
for (int i = 0, iMax = demods.size(); i < iMax; i++) { for (int i = 0, iMax = demods.size(); i < iMax; i++) {
if (!demods[i]->isActive()) { if (!demods[i]->isActive()) {
@ -111,7 +111,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
freq = roundf((float)freq/(float)snap)*snap; freq = roundf((float)freq/(float)snap)*snap;
} }
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto lastActiveDemodulator = wxGetApp().getDemodMgr().getCurrentModem();
bool isNew = (((waterfallCanvas->isShiftDown() || (lastActiveDemodulator && !lastActiveDemodulator->isActive())) && lastActiveDemodulator) || (!lastActiveDemodulator)); bool isNew = (((waterfallCanvas->isShiftDown() || (lastActiveDemodulator && !lastActiveDemodulator->isActive())) && lastActiveDemodulator) || (!lastActiveDemodulator));

View File

@ -62,7 +62,7 @@ TuningCanvas::~TuningCanvas() {
bool TuningCanvas::changed() { bool TuningCanvas::changed() {
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
long long current_freq = 0; long long current_freq = 0;
if (activeDemod != nullptr) { if (activeDemod != nullptr) {
@ -93,7 +93,7 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->DrawBegin(); glContext->DrawBegin();
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
freq = 0; freq = 0;
if (activeDemod != nullptr) { if (activeDemod != nullptr) {
@ -171,7 +171,7 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) {
amount *= 2; amount *= 2;
} }
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
if (state == TUNING_HOVER_FREQ && activeDemod) { if (state == TUNING_HOVER_FREQ && activeDemod) {
long long freq = activeDemod->getFrequency(); long long freq = activeDemod->getFrequency();
long long diff = abs(wxGetApp().getFrequency() - freq); long long diff = abs(wxGetApp().getFrequency() - freq);
@ -328,7 +328,7 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) {
} }
if (hoverState == TUNING_HOVER_BW || hoverState == TUNING_HOVER_FREQ) { if (hoverState == TUNING_HOVER_BW || hoverState == TUNING_HOVER_FREQ) {
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getLastActiveDemodulator()); wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getCurrentModem());
} else { } else {
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr); wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
} }

View File

@ -267,11 +267,11 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
auto demods = wxGetApp().getDemodMgr().getDemodulators(); auto demods = wxGetApp().getDemodMgr().getDemodulators();
auto activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator(); auto activeDemodulator = wxGetApp().getDemodMgr().getActiveContextModem();
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator(); auto lastActiveDemodulator = wxGetApp().getDemodMgr().getCurrentModem();
bool isNew = shiftDown bool isNew = shiftDown
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); || (wxGetApp().getDemodMgr().getCurrentModem() && !wxGetApp().getDemodMgr().getCurrentModem()->isActive());
int currentBandwidth = getBandwidth(); int currentBandwidth = getBandwidth();
long long currentCenterFreq = getCenterFrequency(); long long currentCenterFreq = getCenterFrequency();
@ -279,7 +279,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme; ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme;
std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType(); std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
if (mouseTracker.mouseInView() || wxGetApp().getDemodMgr().getActiveDemodulator()) { if (mouseTracker.mouseInView() || wxGetApp().getDemodMgr().getActiveContextModem()) {
hoverAlpha += (1.0f-hoverAlpha)*0.1f; hoverAlpha += (1.0f-hoverAlpha)*0.1f;
if (hoverAlpha > 1.5f) { if (hoverAlpha > 1.5f) {
hoverAlpha = 1.5f; hoverAlpha = 1.5f;
@ -392,7 +392,7 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
InteractiveCanvas::OnKeyDown(event); InteractiveCanvas::OnKeyDown(event);
auto activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator(); auto activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
long long originalFreq = getCenterFrequency(); long long originalFreq = getCenterFrequency();
long long freq = originalFreq; long long freq = originalFreq;
@ -449,8 +449,8 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
wxGetApp().showLabelInput(); wxGetApp().showLabelInput();
break; break;
case 'C': case 'C':
if (wxGetApp().getDemodMgr().getActiveDemodulator()) { if (wxGetApp().getDemodMgr().getActiveContextModem()) {
wxGetApp().setFrequency(wxGetApp().getDemodMgr().getActiveDemodulator()->getFrequency()); wxGetApp().setFrequency(wxGetApp().getDemodMgr().getActiveContextModem()->getFrequency());
} else if (mouseTracker.mouseInView()) { } else if (mouseTracker.mouseInView()) {
long long freq = getFrequencyAt(mouseTracker.getMouseX()); long long freq = getFrequencyAt(mouseTracker.getMouseX());
@ -589,7 +589,7 @@ void WaterfallCanvas::updateHoverState() {
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
InteractiveCanvas::OnMouseMoved(event); InteractiveCanvas::OnMouseMoved(event);
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator(); auto demod = wxGetApp().getDemodMgr().getActiveContextModem();
if (mouseTracker.mouseDown()) { if (mouseTracker.mouseDown()) {
if (demod == nullptr) { if (demod == nullptr) {
@ -654,12 +654,12 @@ void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) {
wxGetApp().getDemodMgr().updateLastState(); wxGetApp().getDemodMgr().updateLastState();
if (dragState && dragState != WF_DRAG_RANGE) { if (dragState && dragState != WF_DRAG_RANGE) {
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator(); auto demod = wxGetApp().getDemodMgr().getActiveContextModem();
if (demod) { if (demod) {
dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency(); dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency();
dragBW = demod->getBandwidth(); dragBW = demod->getBandwidth();
} }
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveDemodulator(), false); wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveContextModem(), false);
} }
} }
@ -674,14 +674,14 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
InteractiveCanvas::OnMouseReleased(event); InteractiveCanvas::OnMouseReleased(event);
wxGetApp().getDemodMgr().updateLastState(); wxGetApp().getDemodMgr().updateLastState();
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr) bool isNew = shiftDown || (wxGetApp().getDemodMgr().getCurrentModem() == nullptr)
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); || (wxGetApp().getDemodMgr().getCurrentModem() && !wxGetApp().getDemodMgr().getCurrentModem()->isActive());
mouseTracker.setVertDragLock(false); mouseTracker.setVertDragLock(false);
mouseTracker.setHorizDragLock(false); mouseTracker.setHorizDragLock(false);
DemodulatorInstancePtr demod = isNew?nullptr:wxGetApp().getDemodMgr().getLastActiveDemodulator(); DemodulatorInstancePtr demod = isNew?nullptr: wxGetApp().getDemodMgr().getCurrentModem();
DemodulatorInstancePtr activeDemod = isNew?nullptr:wxGetApp().getDemodMgr().getActiveDemodulator(); DemodulatorInstancePtr activeDemod = isNew?nullptr: wxGetApp().getDemodMgr().getActiveContextModem();
DemodulatorMgr *mgr = &wxGetApp().getDemodMgr(); DemodulatorMgr *mgr = &wxGetApp().getDemodMgr();
@ -710,7 +710,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
if (dragState == WF_DRAG_NONE) { if (dragState == WF_DRAG_NONE) {
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) { if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
mgr->updateLastState(); mgr->updateLastState();
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); demod = wxGetApp().getDemodMgr().getCurrentModem();
} else { } else {
isNew = true; isNew = true;
demod = wxGetApp().getDemodMgr().newThread(); demod = wxGetApp().getDemodMgr().newThread();
@ -811,7 +811,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) { if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
mgr->updateLastState(); mgr->updateLastState();
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); demod = wxGetApp().getDemodMgr().getCurrentModem();
} else { } else {
demod = wxGetApp().getDemodMgr().newThread(); demod = wxGetApp().getDemodMgr().newThread();
demod->setFrequency(freq); demod->setFrequency(freq);