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/ModemProperties.cpp
|
||||
src/BookmarkMgr.cpp
|
||||
src/SessionMgr.cpp
|
||||
src/sdr/SDRDeviceInfo.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/sdr/SDREnumerator.cpp
|
||||
@ -433,6 +434,7 @@ SET (cubicsdr_headers
|
||||
src/IOThread.h
|
||||
src/ModemProperties.h
|
||||
src/BookmarkMgr.h
|
||||
src/SessionMgr.h
|
||||
src/sdr/SDRDeviceInfo.h
|
||||
src/sdr/SDRPostThread.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 <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_SET_FREQ_OFFSET 2001
|
||||
#define wxID_RESET 2002
|
||||
@ -98,210 +384,4 @@
|
||||
#define wxID_RIG_FOLLOW_MODEM 11906
|
||||
#define wxID_RIG_SERIAL_BASE 11950
|
||||
#define wxID_RIG_MODEL_BASE 12000
|
||||
#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();
|
||||
};
|
||||
#endif
|
@ -216,6 +216,27 @@ CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFA
|
||||
*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() {
|
||||
|
||||
//use the current locale most appropriate to this system,
|
||||
@ -298,6 +319,8 @@ bool CubicSDR::OnInit() {
|
||||
devicesFailed.store(false);
|
||||
deviceSelectorOpen.store(false);
|
||||
|
||||
initAudioDevices();
|
||||
|
||||
// Visual Data
|
||||
spectrumVisualThread = new SpectrumVisualDataThread();
|
||||
|
||||
@ -841,12 +864,16 @@ DemodulatorThreadInputQueuePtr CubicSDR::getWaterfallVisualQueue() {
|
||||
return pipeWaterfallIQVisualData;
|
||||
}
|
||||
|
||||
BookmarkMgr &CubicSDR::getBookmarkMgr() {
|
||||
return bookmarkMgr;
|
||||
}
|
||||
|
||||
DemodulatorMgr &CubicSDR::getDemodMgr() {
|
||||
return demodMgr;
|
||||
}
|
||||
|
||||
BookmarkMgr &CubicSDR::getBookmarkMgr() {
|
||||
return bookmarkMgr;
|
||||
SessionMgr &CubicSDR::getSessionMgr() {
|
||||
return sessionMgr;
|
||||
}
|
||||
|
||||
SDRPostThread *CubicSDR::getSDRPostThread() {
|
||||
@ -917,7 +944,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
|
||||
switch (targetMode) {
|
||||
case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
|
||||
case FrequencyDialog::FDIALOG_TARGET_FREQ:
|
||||
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
|
||||
title = demodMgr.getActiveContextModem()?demodTitle:freqTitle;
|
||||
break;
|
||||
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
|
||||
title = bwTitle;
|
||||
@ -938,13 +965,13 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
|
||||
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();
|
||||
}
|
||||
|
||||
void CubicSDR::showLabelInput() {
|
||||
|
||||
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
|
||||
if (activeDemod != nullptr) {
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "FrequencyDialog.h"
|
||||
#include "DemodLabelDialog.h"
|
||||
#include "BookmarkMgr.h"
|
||||
#include "SessionMgr.h"
|
||||
|
||||
#include "ScopeVisualProcessor.h"
|
||||
#include "SpectrumVisualProcessor.h"
|
||||
@ -119,6 +120,7 @@ public:
|
||||
|
||||
DemodulatorMgr &getDemodMgr();
|
||||
BookmarkMgr &getBookmarkMgr();
|
||||
SessionMgr &getSessionMgr();
|
||||
|
||||
SDRPostThread *getSDRPostThread();
|
||||
SDRThread *getSDRThread();
|
||||
@ -194,6 +196,7 @@ private:
|
||||
|
||||
DemodulatorMgr demodMgr;
|
||||
BookmarkMgr bookmarkMgr;
|
||||
SessionMgr sessionMgr;
|
||||
|
||||
std::atomic_llong frequency;
|
||||
std::atomic_llong offset;
|
||||
@ -248,6 +251,8 @@ private:
|
||||
RigThread* rigThread = nullptr;
|
||||
std::thread *t_Rig = nullptr;
|
||||
#endif
|
||||
|
||||
void initAudioDevices() const;
|
||||
};
|
||||
|
||||
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
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
|
@ -97,7 +97,7 @@ std::vector<DemodulatorInstancePtr> DemodulatorMgr::getOrderedDemodulators(bool
|
||||
|
||||
DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstancePtr demod, bool actives) {
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
if (!getLastActiveDemodulator()) {
|
||||
if (!getCurrentModem()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto demods_ordered = getOrderedDemodulators(actives);
|
||||
@ -114,7 +114,7 @@ DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstanc
|
||||
|
||||
DemodulatorInstancePtr DemodulatorMgr::getNextDemodulator(DemodulatorInstancePtr demod, bool actives) {
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
if (!getLastActiveDemodulator()) {
|
||||
if (!getCurrentModem()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto demods_ordered = getOrderedDemodulators(actives);
|
||||
@ -152,11 +152,11 @@ void DemodulatorMgr::deleteThread(DemodulatorInstancePtr demod) {
|
||||
|
||||
auto i = std::find(demods.begin(), demods.end(), demod);
|
||||
|
||||
if (activeDemodulator == demod) {
|
||||
activeDemodulator = nullptr;
|
||||
if (activeContextModem == demod) {
|
||||
activeContextModem = nullptr;
|
||||
}
|
||||
if (lastActiveDemodulator == demod) {
|
||||
lastActiveDemodulator = nullptr;
|
||||
if (currentModem == demod) {
|
||||
currentModem = nullptr;
|
||||
}
|
||||
if (activeVisualDemodulator == demod) {
|
||||
activeVisualDemodulator = nullptr;
|
||||
@ -215,25 +215,30 @@ bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
|
||||
|
||||
|
||||
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool temporary) {
|
||||
|
||||
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
|
||||
|
||||
// Should this be made the current modem (i.e. clicked, toggled)
|
||||
if (!temporary) {
|
||||
if (activeDemodulator != nullptr) {
|
||||
lastActiveDemodulator = activeDemodulator;
|
||||
if (activeContextModem != nullptr) {
|
||||
currentModem = activeContextModem;
|
||||
updateLastState();
|
||||
} else {
|
||||
lastActiveDemodulator = demod;
|
||||
currentModem = demod;
|
||||
}
|
||||
|
||||
updateLastState();
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
|
||||
#if USE_HAMLIB
|
||||
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && lastActiveDemodulator) {
|
||||
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator->getFrequency(),true);
|
||||
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && currentModem) {
|
||||
wxGetApp().getRigThread()->setFrequency(currentModem->getFrequency(),true);
|
||||
}
|
||||
#endif
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This is probably unnecessary and confusing
|
||||
if (activeVisualDemodulator) {
|
||||
activeVisualDemodulator->setVisualOutputQueue(nullptr);
|
||||
}
|
||||
@ -241,15 +246,15 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool tem
|
||||
demod->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
|
||||
activeVisualDemodulator = demod;
|
||||
} else {
|
||||
DemodulatorInstancePtr last = getLastActiveDemodulator();
|
||||
DemodulatorInstancePtr last = getCurrentModem();
|
||||
if (last) {
|
||||
last->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
|
||||
}
|
||||
activeVisualDemodulator = last;
|
||||
}
|
||||
// :ODOT
|
||||
|
||||
activeDemodulator = demod;
|
||||
|
||||
activeContextModem = demod;
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
if (activeDemodulator && !activeDemodulator->isActive()) {
|
||||
activeDemodulator = getLastActiveDemodulator();
|
||||
if (activeContextModem && !activeContextModem->isActive()) {
|
||||
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,
|
||||
@ -304,27 +319,27 @@ DemodulatorInstancePtr DemodulatorMgr::getLastDemodulatorWith(const std::string&
|
||||
void DemodulatorMgr::updateLastState() {
|
||||
std::lock_guard < std::recursive_mutex > lock(demods_busy);
|
||||
|
||||
if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) {
|
||||
if (activeDemodulator && activeDemodulator->isActive()) {
|
||||
lastActiveDemodulator = activeDemodulator;
|
||||
} else if (activeDemodulator && !activeDemodulator->isActive()){
|
||||
activeDemodulator = nullptr;
|
||||
lastActiveDemodulator = nullptr;
|
||||
if (std::find(demods.begin(), demods.end(), currentModem) == demods.end()) {
|
||||
if (activeContextModem && activeContextModem->isActive()) {
|
||||
currentModem = activeContextModem;
|
||||
} else if (activeContextModem && !activeContextModem->isActive()){
|
||||
activeContextModem = nullptr;
|
||||
currentModem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastActiveDemodulator && !lastActiveDemodulator->isActive()) {
|
||||
lastActiveDemodulator = nullptr;
|
||||
if (currentModem && !currentModem->isActive()) {
|
||||
currentModem = nullptr;
|
||||
}
|
||||
|
||||
if (lastActiveDemodulator) {
|
||||
lastBandwidth = lastActiveDemodulator->getBandwidth();
|
||||
lastDemodType = lastActiveDemodulator->getDemodulatorType();
|
||||
lastDemodLock = lastActiveDemodulator->getDemodulatorLock()?true:false;
|
||||
lastSquelchEnabled = lastActiveDemodulator->isSquelchEnabled();
|
||||
lastSquelch = lastActiveDemodulator->getSquelchLevel();
|
||||
lastGain = lastActiveDemodulator->getGain();
|
||||
lastModemSettings[lastDemodType] = lastActiveDemodulator->readModemSettings();
|
||||
if (currentModem) {
|
||||
lastBandwidth = currentModem->getBandwidth();
|
||||
lastDemodType = currentModem->getDemodulatorType();
|
||||
lastDemodLock = currentModem->getDemodulatorLock()?true:false;
|
||||
lastSquelchEnabled = currentModem->isSquelchEnabled();
|
||||
lastSquelch = currentModem->getSquelchLevel();
|
||||
lastGain = currentModem->getGain();
|
||||
lastModemSettings[lastDemodType] = currentModem->readModemSettings();
|
||||
}
|
||||
|
||||
}
|
||||
@ -403,6 +418,10 @@ void DemodulatorMgr::setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs) {
|
||||
outputDevices = devs;
|
||||
}
|
||||
|
||||
std::map<int, RtAudio::DeviceInfo> DemodulatorMgr::getOutputDevices() {
|
||||
return outputDevices;
|
||||
}
|
||||
|
||||
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstancePtr inst) {
|
||||
|
||||
*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_ofs") = inst->getDeltaLockOfs();
|
||||
}
|
||||
if (inst == getLastActiveDemodulator()) {
|
||||
if (inst == getCurrentModem()) {
|
||||
*node->newChild("active") = 1;
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
// and only set a pre-existing demod
|
||||
void setActiveDemodulatorByRawPointer(DemodulatorInstance* demod, bool temporary = true);
|
||||
|
||||
DemodulatorInstancePtr getActiveDemodulator();
|
||||
DemodulatorInstancePtr getLastActiveDemodulator();
|
||||
DemodulatorInstancePtr getActiveContextModem();
|
||||
DemodulatorInstancePtr getCurrentModem();
|
||||
DemodulatorInstancePtr getLastDemodulatorWith(const std::string& type,
|
||||
const std::wstring& userLabel,
|
||||
long long frequency,
|
||||
@ -73,6 +73,7 @@ public:
|
||||
void updateLastState();
|
||||
|
||||
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
|
||||
std::map<int, RtAudio::DeviceInfo> getOutputDevices();
|
||||
void saveInstance(DataNode *node, DemodulatorInstancePtr inst);
|
||||
|
||||
DemodulatorInstancePtr loadInstance(DataNode *node);
|
||||
@ -86,8 +87,8 @@ private:
|
||||
|
||||
std::vector<DemodulatorInstancePtr> demods;
|
||||
|
||||
DemodulatorInstancePtr activeDemodulator;
|
||||
DemodulatorInstancePtr lastActiveDemodulator;
|
||||
DemodulatorInstancePtr activeContextModem;
|
||||
DemodulatorInstancePtr currentModem;
|
||||
DemodulatorInstancePtr activeVisualDemodulator;
|
||||
|
||||
int lastBandwidth;
|
||||
|
@ -322,7 +322,8 @@ void DemodulatorThread::run() {
|
||||
}
|
||||
|
||||
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
|
||||
if (!audioOutputQueue->try_push(ati)) {
|
||||
|
||||
|
@ -356,7 +356,7 @@ wxTreeItemId BookmarkView::refreshBookmarks() {
|
||||
void BookmarkView::doUpdateActiveList() {
|
||||
|
||||
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
|
||||
//having rebuilding the whole tree.
|
||||
|
@ -73,8 +73,8 @@ void RigThread::run() {
|
||||
while (!stopping) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(150));
|
||||
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
auto lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
auto lastDemod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
if (freqChanged.load() && (controlMode.load() || setOneShot.load())) {
|
||||
status = rig_get_freq(rig, RIG_VFO_CURR, &freq);
|
||||
|
@ -69,7 +69,7 @@ void SDRPostThread::updateActiveDemodulators() {
|
||||
if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
|
||||
// deactivate if active
|
||||
|
||||
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == demod) {
|
||||
if (wxGetApp().getDemodMgr().getCurrentModem() == demod) {
|
||||
|
||||
demod->setActive(false);
|
||||
}
|
||||
@ -84,7 +84,7 @@ void SDRPostThread::updateActiveDemodulators() {
|
||||
}
|
||||
} else if (!demod->isActive()) { // in range, activate if not activated
|
||||
demod->setActive(true);
|
||||
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr) {
|
||||
if (wxGetApp().getDemodMgr().getCurrentModem() == nullptr) {
|
||||
|
||||
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
|
||||
void SDRPostThread::runDemodChannels(int channelBandwidth) {
|
||||
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
// Calculate channel data size
|
||||
size_t chanDataSize = dataOut.size()/numChannels;
|
||||
|
@ -108,7 +108,7 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstancePtr demod, RGBA4f color,
|
||||
|
||||
bool soloMode = wxGetApp().getSoloMode();
|
||||
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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
long long bw = 0;
|
||||
|
||||
|
@ -91,7 +91,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
glLoadIdentity();
|
||||
|
||||
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++) {
|
||||
if (!demods[i]->isActive()) {
|
||||
@ -111,7 +111,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
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));
|
||||
|
||||
|
@ -62,7 +62,7 @@ TuningCanvas::~TuningCanvas() {
|
||||
|
||||
bool TuningCanvas::changed() {
|
||||
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
long long current_freq = 0;
|
||||
if (activeDemod != nullptr) {
|
||||
@ -93,7 +93,7 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
|
||||
glContext->DrawBegin();
|
||||
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
freq = 0;
|
||||
if (activeDemod != nullptr) {
|
||||
@ -171,7 +171,7 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) {
|
||||
amount *= 2;
|
||||
}
|
||||
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
if (state == TUNING_HOVER_FREQ && activeDemod) {
|
||||
long long freq = activeDemod->getFrequency();
|
||||
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) {
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getLastActiveDemodulator());
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getCurrentModem());
|
||||
} else {
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
|
||||
}
|
||||
|
@ -267,11 +267,11 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
|
||||
auto demods = wxGetApp().getDemodMgr().getDemodulators();
|
||||
|
||||
auto activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
auto activeDemodulator = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
|
||||
bool isNew = shiftDown
|
||||
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
|
||||
|| (wxGetApp().getDemodMgr().getCurrentModem() && !wxGetApp().getDemodMgr().getCurrentModem()->isActive());
|
||||
|
||||
int currentBandwidth = getBandwidth();
|
||||
long long currentCenterFreq = getCenterFrequency();
|
||||
@ -279,7 +279,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme;
|
||||
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;
|
||||
if (hoverAlpha > 1.5f) {
|
||||
hoverAlpha = 1.5f;
|
||||
@ -392,7 +392,7 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
|
||||
void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
InteractiveCanvas::OnKeyDown(event);
|
||||
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
auto activeDemod = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
|
||||
long long originalFreq = getCenterFrequency();
|
||||
long long freq = originalFreq;
|
||||
@ -449,8 +449,8 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
wxGetApp().showLabelInput();
|
||||
break;
|
||||
case 'C':
|
||||
if (wxGetApp().getDemodMgr().getActiveDemodulator()) {
|
||||
wxGetApp().setFrequency(wxGetApp().getDemodMgr().getActiveDemodulator()->getFrequency());
|
||||
if (wxGetApp().getDemodMgr().getActiveContextModem()) {
|
||||
wxGetApp().setFrequency(wxGetApp().getDemodMgr().getActiveContextModem()->getFrequency());
|
||||
} else if (mouseTracker.mouseInView()) {
|
||||
long long freq = getFrequencyAt(mouseTracker.getMouseX());
|
||||
|
||||
@ -589,7 +589,7 @@ void WaterfallCanvas::updateHoverState() {
|
||||
|
||||
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseMoved(event);
|
||||
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
auto demod = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
|
||||
if (mouseTracker.mouseDown()) {
|
||||
if (demod == nullptr) {
|
||||
@ -654,12 +654,12 @@ void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) {
|
||||
wxGetApp().getDemodMgr().updateLastState();
|
||||
|
||||
if (dragState && dragState != WF_DRAG_RANGE) {
|
||||
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
auto demod = wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
if (demod) {
|
||||
dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency();
|
||||
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);
|
||||
wxGetApp().getDemodMgr().updateLastState();
|
||||
|
||||
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr)
|
||||
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
|
||||
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getCurrentModem() == nullptr)
|
||||
|| (wxGetApp().getDemodMgr().getCurrentModem() && !wxGetApp().getDemodMgr().getCurrentModem()->isActive());
|
||||
|
||||
mouseTracker.setVertDragLock(false);
|
||||
mouseTracker.setHorizDragLock(false);
|
||||
|
||||
DemodulatorInstancePtr demod = isNew?nullptr:wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
DemodulatorInstancePtr activeDemod = isNew?nullptr:wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
DemodulatorInstancePtr demod = isNew?nullptr: wxGetApp().getDemodMgr().getCurrentModem();
|
||||
DemodulatorInstancePtr activeDemod = isNew?nullptr: wxGetApp().getDemodMgr().getActiveContextModem();
|
||||
|
||||
DemodulatorMgr *mgr = &wxGetApp().getDemodMgr();
|
||||
|
||||
@ -710,7 +710,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
|
||||
if (dragState == WF_DRAG_NONE) {
|
||||
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
|
||||
mgr->updateLastState();
|
||||
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
demod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
} else {
|
||||
isNew = true;
|
||||
demod = wxGetApp().getDemodMgr().newThread();
|
||||
@ -811,7 +811,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
|
||||
|
||||
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
|
||||
mgr->updateLastState();
|
||||
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
demod = wxGetApp().getDemodMgr().getCurrentModem();
|
||||
} else {
|
||||
demod = wxGetApp().getDemodMgr().newThread();
|
||||
demod->setFrequency(freq);
|
||||
|
Loading…
x
Reference in New Issue
Block a user