mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-09-07 23:57:50 -04:00
Merge pull request #723 from cjcliffe/code_quality
AppFrame refactoring
This commit is contained in:
commit
8edd8a77dc
@ -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
|
||||||
|
2187
src/AppFrame.cpp
2187
src/AppFrame.cpp
File diff suppressed because it is too large
Load Diff
494
src/AppFrame.h
494
src/AppFrame.h
@ -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
|
||||||
@ -98,210 +384,4 @@
|
|||||||
#define wxID_RIG_FOLLOW_MODEM 11906
|
#define wxID_RIG_FOLLOW_MODEM 11906
|
||||||
#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();
|
|
||||||
};
|
|
@ -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) {
|
||||||
|
|
||||||
|
@ -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
195
src/SessionMgr.cpp
Normal 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
14
src/SessionMgr.h
Normal 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);
|
||||||
|
};
|
@ -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
|
||||||
|
@ -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;
|
||||||
@ -215,25 +215,30 @@ bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
|
|||||||
|
|
||||||
|
|
||||||
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool temporary) {
|
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool temporary) {
|
||||||
|
|
||||||
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();
|
updateLastState();
|
||||||
|
|
||||||
|
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||||
|
|
||||||
#if USE_HAMLIB
|
#if USE_HAMLIB
|
||||||
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && lastActiveDemodulator) {
|
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && currentModem) {
|
||||||
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator->getFrequency(),true);
|
wxGetApp().getRigThread()->setFrequency(currentModem->getFrequency(),true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user