mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2026-06-11 10:18:52 -04:00
Merge branch 'develop' into master
This commit is contained in:
+228
-185
@@ -23,6 +23,7 @@
|
||||
#include "DataTree.h"
|
||||
#include "ColorTheme.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "ImagePanel.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -46,6 +47,10 @@ wxEND_EVENT_TABLE()
|
||||
#include "RigThread.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* split a string by 'seperator' into a vector of string */
|
||||
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str);
|
||||
|
||||
#define APPFRAME_MODEMPROPS_MINSIZE 20
|
||||
#define APPFRAME_MODEMPROPS_MAXSIZE 240
|
||||
|
||||
@@ -57,7 +62,6 @@ AppFrame::AppFrame() :
|
||||
#endif
|
||||
|
||||
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
|
||||
demodTray = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *demodTunerTray = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -68,10 +72,30 @@ AppFrame::AppFrame() :
|
||||
//attribList.PlatformDefaults().MinRGBA(8, 8, 8, 8).DoubleBuffer().Depth(16).EndList();
|
||||
|
||||
mainSplitter = new wxSplitterWindow( this, wxID_MAIN_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainSplitter->SetSashGravity(10.0/37.0);
|
||||
mainSplitter->SetSashGravity(10.0f / 37.0f);
|
||||
mainSplitter->SetMinimumPaneSize(1);
|
||||
|
||||
|
||||
wxPanel *demodPanel = new wxPanel(mainSplitter, wxID_ANY);
|
||||
|
||||
#ifdef CUBICSDR_HEADER_IMAGE
|
||||
wxFileName exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath());
|
||||
std::string headerPath = exePath.GetPath().ToStdString();
|
||||
headerPath += filePathSeparator + std::string("" CUBICSDR_HEADER_IMAGE);
|
||||
wxInitAllImageHandlers();
|
||||
|
||||
ImagePanel *imgPanel = new ImagePanel(demodPanel, headerPath, wxBITMAP_TYPE_ANY);
|
||||
|
||||
std::string headerBgColor = "" CUBICSDR_HEADER_BG;
|
||||
if (headerBgColor != "") {
|
||||
imgPanel->SetBackgroundColour(wxColour(headerBgColor));
|
||||
}
|
||||
|
||||
imgPanel->SetBestFittingSize(wxSize(200, 0));
|
||||
|
||||
demodTray->Add(imgPanel, 0, wxEXPAND | wxALL, 0);
|
||||
demodTray->AddSpacer(1);
|
||||
#endif
|
||||
|
||||
gainCanvas = new GainCanvas(demodPanel, attribList);
|
||||
|
||||
@@ -80,16 +104,24 @@ AppFrame::AppFrame() :
|
||||
gainSpacerItem = demodTray->AddSpacer(1);
|
||||
gainSpacerItem->Show(false);
|
||||
|
||||
std::string modemListArr[] = { "FM", "FMS", "NBFM", "AM", "LSB", "USB", "DSB", "I/Q" };
|
||||
std::vector<std::string> modemList( modemListArr, modemListArr + 8 );
|
||||
|
||||
#ifdef CUBICSDR_MODEM_EXCLUDE
|
||||
std::string excludeListStr = "" CUBICSDR_MODEM_EXCLUDE;
|
||||
std::vector<std::string> excludeList = str_explode(",",excludeListStr);
|
||||
for (auto ex_i : excludeList) {
|
||||
std::vector<std::string>::iterator found_i = std::find(modemList.begin(),modemList.end(),ex_i);
|
||||
if (found_i != modemList.end()) {
|
||||
modemList.erase(found_i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
demodModeSelector = new ModeSelectorCanvas(demodPanel, attribList);
|
||||
demodModeSelector->addChoice("FM");
|
||||
demodModeSelector->addChoice("FMS");
|
||||
demodModeSelector->addChoice("NBFM");
|
||||
demodModeSelector->addChoice("AM");
|
||||
demodModeSelector->addChoice("LSB");
|
||||
demodModeSelector->addChoice("USB");
|
||||
demodModeSelector->addChoice("DSB");
|
||||
demodModeSelector->addChoice("I/Q");
|
||||
demodModeSelector->setSelection("FM");
|
||||
for (auto mt_i : modemList) {
|
||||
demodModeSelector->addChoice(mt_i);
|
||||
}
|
||||
demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation (Hotkey F), Amplitude Modulation (A) and Lower (L), Upper (U), Double Side-Band and more.");
|
||||
demodModeSelector->SetMinSize(wxSize(50,-1));
|
||||
demodModeSelector->SetMaxSize(wxSize(50,-1));
|
||||
@@ -120,13 +152,19 @@ AppFrame::AppFrame() :
|
||||
modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_MAXSIZE,-1));
|
||||
modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_MAXSIZE,-1));
|
||||
|
||||
modemProps->Hide();
|
||||
ModemArgInfoList dummyInfo;
|
||||
modemProps->initProperties(dummyInfo, nullptr);
|
||||
modemProps->updateTheme();
|
||||
|
||||
demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0);
|
||||
|
||||
#ifndef __APPLE__
|
||||
demodTray->AddSpacer(1);
|
||||
#endif
|
||||
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_DEMOD
|
||||
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxGetApp().getDemodSpectrumProcessor()->setup(1024);
|
||||
demodSpectrumCanvas = new SpectrumCanvas(demodPanel, attribList);
|
||||
demodSpectrumCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000);
|
||||
@@ -150,7 +188,11 @@ AppFrame::AppFrame() :
|
||||
demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0);
|
||||
|
||||
demodTray->AddSpacer(1);
|
||||
|
||||
#else
|
||||
demodSpectrumCanvas = nullptr;
|
||||
demodWaterfallCanvas = nullptr;
|
||||
#endif
|
||||
|
||||
demodSignalMeter = new MeterCanvas(demodPanel, attribList);
|
||||
demodSignalMeter->setMax(DEMOD_SIGNAL_MAX);
|
||||
demodSignalMeter->setMin(DEMOD_SIGNAL_MIN);
|
||||
@@ -163,6 +205,7 @@ AppFrame::AppFrame() :
|
||||
|
||||
demodTray->AddSpacer(1);
|
||||
|
||||
#if CUBICSDR_ENABLE_VIEW_SCOPE
|
||||
scopeCanvas = new ScopeCanvas(demodPanel, attribList);
|
||||
scopeCanvas->setHelpTip("Audio Visuals, drag left/right to toggle Scope or Spectrum.");
|
||||
scopeCanvas->SetMinSize(wxSize(128,-1));
|
||||
@@ -171,7 +214,10 @@ AppFrame::AppFrame() :
|
||||
wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue());
|
||||
|
||||
demodScopeTray->AddSpacer(1);
|
||||
|
||||
#else
|
||||
scopeCanvas = nullptr;
|
||||
#endif
|
||||
|
||||
deltaLockButton = new ModeSelectorCanvas(demodPanel, attribList);
|
||||
deltaLockButton->addChoice(1, "V");
|
||||
deltaLockButton->setPadding(-1,-1);
|
||||
@@ -235,10 +281,13 @@ AppFrame::AppFrame() :
|
||||
|
||||
// vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0);
|
||||
// vbox->AddSpacer(1);
|
||||
|
||||
mainVisSplitter = new wxSplitterWindow( mainSplitter, wxID_VIS_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainVisSplitter->SetSashGravity(6.0/25.0);
|
||||
bookmarkSplitter = new wxSplitterWindow( mainSplitter, wxID_BM_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
bookmarkSplitter->SetMinimumPaneSize(1);
|
||||
bookmarkSplitter->SetSashGravity(1.0f / 20.0f);
|
||||
|
||||
mainVisSplitter = new wxSplitterWindow( bookmarkSplitter, wxID_VIS_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
|
||||
mainVisSplitter->SetMinimumPaneSize(1);
|
||||
mainVisSplitter->SetSashGravity(6.0f / 25.0f);
|
||||
|
||||
// mainVisSplitter->Connect( wxEVT_IDLE, wxIdleEventHandler( AppFrame::mainVisSplitterIdle ), NULL, this );
|
||||
|
||||
@@ -248,6 +297,7 @@ AppFrame::AppFrame() :
|
||||
wxGetApp().getSpectrumProcessor()->setup(2048);
|
||||
spectrumCanvas = new SpectrumCanvas(spectrumPanel, attribList);
|
||||
spectrumCanvas->setShowDb(true);
|
||||
spectrumCanvas->setUseDBOfs(true);
|
||||
spectrumCanvas->setScaleFactorEnabled(true);
|
||||
wxGetApp().getSpectrumProcessor()->attachOutput(spectrumCanvas->getVisualDataQueue());
|
||||
|
||||
@@ -312,10 +362,19 @@ AppFrame::AppFrame() :
|
||||
// vbox->Add(wfSizer, 20, wxEXPAND | wxALL, 0);
|
||||
|
||||
mainVisSplitter->SplitHorizontally( spectrumPanel, waterfallPanel, 0 );
|
||||
mainSplitter->SplitHorizontally( demodPanel, mainVisSplitter );
|
||||
|
||||
bookmarkView = new BookmarkView(bookmarkSplitter, wxID_ANY, wxDefaultPosition, wxSize(120,-1));
|
||||
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter );
|
||||
mainSplitter->SplitHorizontally( demodPanel, bookmarkSplitter );
|
||||
|
||||
if (!wxGetApp().getConfig()->getBookmarksVisible()) {
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->Layout();
|
||||
}
|
||||
|
||||
vbox->Add(mainSplitter, 1, wxEXPAND | wxALL, 0);
|
||||
|
||||
|
||||
// TODO: refactor these..
|
||||
waterfallCanvas->attachSpectrumCanvas(spectrumCanvas);
|
||||
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
|
||||
@@ -378,6 +437,8 @@ AppFrame::AppFrame() :
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
wxGetApp().getDemodMgr().setOutputDevices(outputDevices);
|
||||
//
|
||||
// for (mdevices_i = outputDevices.begin(); mdevices_i != outputDevices.end(); mdevices_i++) {
|
||||
// wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE + mdevices_i->first, mdevices_i->second.name, wxT("Description?"));
|
||||
@@ -470,6 +531,9 @@ AppFrame::AppFrame() :
|
||||
themeMenu->AppendRadioItem(wxID_THEME_HD, "HD")->Check(themeId==COLOR_THEME_HD);
|
||||
|
||||
displayMenu->AppendSubMenu(themeMenu, wxT("&Color Scheme"));
|
||||
|
||||
hideBookmarksItem = displayMenu->AppendCheckItem(wxID_DISPLAY_BOOKMARKS, wxT("Hide Bookmarks"));
|
||||
hideBookmarksItem->Check(!wxGetApp().getConfig()->getBookmarksVisible());
|
||||
|
||||
GLFont::setScale((GLFont::GLFontScale)fontScale);
|
||||
|
||||
@@ -588,13 +652,27 @@ AppFrame::AppFrame() :
|
||||
waterfallCanvas->setLinesPerSecond(wflps);
|
||||
|
||||
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
|
||||
bookmarkView->updateTheme();
|
||||
|
||||
int mpc =wxGetApp().getConfig()->getModemPropsCollapsed();
|
||||
|
||||
if (mpc) {
|
||||
modemProps->setCollapsed(true);
|
||||
}
|
||||
|
||||
|
||||
int msPos = wxGetApp().getConfig()->getMainSplit();
|
||||
if (msPos != -1) {
|
||||
mainSplitter->SetSashPosition(msPos);
|
||||
}
|
||||
int bsPos = wxGetApp().getConfig()->getBookmarkSplit();
|
||||
if (bsPos != -1) {
|
||||
bookmarkSplitter->SetSashPosition(bsPos);
|
||||
}
|
||||
int vsPos = wxGetApp().getConfig()->getVisSplit();
|
||||
if (vsPos != -1) {
|
||||
mainVisSplitter->SetSashPosition(vsPos);
|
||||
}
|
||||
|
||||
Show();
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -611,6 +689,7 @@ AppFrame::AppFrame() :
|
||||
deviceChanged.store(false);
|
||||
devInfo = NULL;
|
||||
wxGetApp().deviceSelector();
|
||||
saveDisabled = false;
|
||||
|
||||
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
||||
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
|
||||
@@ -652,6 +731,7 @@ void AppFrame::updateDeviceParams() {
|
||||
|
||||
newSettingsMenu->AppendSeparator();
|
||||
|
||||
newSettingsMenu->Append(wxID_SET_DB_OFFSET, "Power Level Offset");
|
||||
newSettingsMenu->Append(wxID_SET_FREQ_OFFSET, "Frequency Offset");
|
||||
|
||||
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
||||
@@ -867,6 +947,12 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
if (ofs != -1) {
|
||||
wxGetApp().setOffset(ofs);
|
||||
}
|
||||
} else if (event.GetId() == wxID_SET_DB_OFFSET) {
|
||||
long ofs = wxGetNumberFromUser("Shift the displayed RF power level by this amount.\ni.e. -30 for -30 dB", "Decibels (dB)",
|
||||
"Power Level Offset", wxGetApp().getConfig()->getDBOffset(), -1000, 1000, this);
|
||||
if (ofs != -1) {
|
||||
wxGetApp().getConfig()->setDBOffset(ofs);
|
||||
}
|
||||
} else if (event.GetId() == wxID_AGC_CONTROL) {
|
||||
if (wxGetApp().getDevice() == NULL) {
|
||||
agcMenuItem->Check(true);
|
||||
@@ -937,6 +1023,9 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
demodTuner->Refresh();
|
||||
SetTitle(CUBICSDR_TITLE);
|
||||
currentSessionFile = "";
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter, wxGetApp().getConfig()->getBookmarkSplit() );
|
||||
hideBookmarksItem->Check(false);
|
||||
} else if (event.GetId() == wxID_CLOSE || event.GetId() == wxID_EXIT) {
|
||||
Close(false);
|
||||
} else if (event.GetId() == wxID_THEME_DEFAULT) {
|
||||
@@ -969,6 +1058,14 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
GLFont::setScale(GLFont::GLFONT_SCALE_LARGE);
|
||||
//force all windows refresh
|
||||
Refresh();
|
||||
} else if (event.GetId() == wxID_DISPLAY_BOOKMARKS) {
|
||||
if (hideBookmarksItem->IsChecked()) {
|
||||
bookmarkSplitter->Unsplit(bookmarkView);
|
||||
bookmarkSplitter->Layout();
|
||||
} else {
|
||||
bookmarkSplitter->SplitVertically( bookmarkView, mainVisSplitter, wxGetApp().getConfig()->getBookmarkSplit() );
|
||||
bookmarkSplitter->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.GetId() >= wxID_SETTINGS_BASE && event.GetId() < settingsIdMax) {
|
||||
@@ -1029,6 +1126,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
spectrumAvgMeter->Refresh();
|
||||
gainCanvas->setThemeColors();
|
||||
modemProps->updateTheme();
|
||||
bookmarkView->updateTheme();
|
||||
}
|
||||
|
||||
switch (event.GetId()) {
|
||||
@@ -1212,10 +1310,17 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().closeDeviceSelector();
|
||||
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodSpectrumCanvas->getVisualDataQueue());
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodWaterfallCanvas->getVisualDataQueue());
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) {
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodSpectrumCanvas->getVisualDataQueue());
|
||||
wxGetApp().getDemodSpectrumProcessor()->removeOutput(demodWaterfallCanvas->getVisualDataQueue());
|
||||
}
|
||||
wxGetApp().getSpectrumProcessor()->removeOutput(spectrumCanvas->getVisualDataQueue());
|
||||
|
||||
if (saveDisabled) {
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
wxGetApp().getConfig()->setWindow(this->GetPosition(), this->GetClientSize());
|
||||
wxGetApp().getConfig()->setWindowMaximized(this->IsMaximized());
|
||||
wxGetApp().getConfig()->setTheme(ThemeMgr::mgr.getTheme());
|
||||
@@ -1226,6 +1331,10 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond());
|
||||
wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals());
|
||||
wxGetApp().getConfig()->setModemPropsCollapsed(modemProps->isCollapsed());
|
||||
wxGetApp().getConfig()->setMainSplit(mainSplitter->GetSashPosition());
|
||||
wxGetApp().getConfig()->setVisSplit(mainVisSplitter->GetSashPosition());
|
||||
if (!hideBookmarksItem->IsChecked()) wxGetApp().getConfig()->setBookmarkSplit(bookmarkSplitter->GetSashPosition());
|
||||
wxGetApp().getConfig()->setBookmarksVisible(!hideBookmarksItem->IsChecked());
|
||||
#ifdef USE_HAMLIB
|
||||
wxGetApp().getConfig()->setRigEnabled(rigEnableMenuItem->IsChecked());
|
||||
wxGetApp().getConfig()->setRigModel(rigModel);
|
||||
@@ -1237,6 +1346,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setRigFollowModem(rigFollowModemMenuItem->IsChecked());
|
||||
#endif
|
||||
wxGetApp().getConfig()->save();
|
||||
wxGetApp().getBookmarkMgr().saveToFile("bookmarks.xml");
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
@@ -1244,6 +1354,7 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
||||
new AppFrame();
|
||||
}
|
||||
|
||||
|
||||
void AppFrame::OnThread(wxCommandEvent& event) {
|
||||
event.Skip();
|
||||
}
|
||||
@@ -1284,7 +1395,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodGainMeter->setInputValue(demod->getGain());
|
||||
wxGetApp().getDemodMgr().setLastGain(demod->getGain());
|
||||
int outputDevice = demod->getOutputDevice();
|
||||
scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
|
||||
if (scopeCanvas) scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
|
||||
// outputDeviceMenuItems[outputDevice]->Check(true);
|
||||
std::string dType = demod->getDemodulatorType();
|
||||
demodModeSelector->setSelection(dType);
|
||||
@@ -1296,7 +1407,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
modemPropertiesUpdated.store(true);
|
||||
demodTuner->setHalfBand(dType=="USB" || dType=="LSB");
|
||||
}
|
||||
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||
if (!demodWaterfallCanvas || demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||
long long centerFreq = demod->getFrequency();
|
||||
unsigned int demodBw = (unsigned int) ceil((float) demod->getBandwidth() * 2.25);
|
||||
|
||||
@@ -1317,7 +1428,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodBw = 20000;
|
||||
}
|
||||
|
||||
if (centerFreq != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
if (demodWaterfallCanvas && centerFreq != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
demodWaterfallCanvas->setCenterFrequency(centerFreq);
|
||||
demodSpectrumCanvas->setCenterFrequency(centerFreq);
|
||||
}
|
||||
@@ -1403,8 +1514,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
demodWaterfallCanvas->setBandwidth(demodBw);
|
||||
demodSpectrumCanvas->setBandwidth(demodBw);
|
||||
if (demodWaterfallCanvas) {
|
||||
demodWaterfallCanvas->setBandwidth(demodBw);
|
||||
demodSpectrumCanvas->setBandwidth(demodBw);
|
||||
}
|
||||
}
|
||||
|
||||
demodSignalMeter->setLevel(demod->getSignalLevel());
|
||||
@@ -1460,9 +1573,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
demodGainMeter->setLevel(demodGainMeter->getInputValue());
|
||||
}
|
||||
|
||||
if (wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
if (demodWaterfallCanvas && wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
if (demodSpectrumCanvas) demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
}
|
||||
if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) {
|
||||
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||
@@ -1479,15 +1592,17 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
scopeCanvas->setPPMMode(demodTuner->isAltDown());
|
||||
if (scopeCanvas) {
|
||||
scopeCanvas->setPPMMode(demodTuner->isAltDown());
|
||||
|
||||
scopeCanvas->setShowDb(spectrumCanvas->getShowDb());
|
||||
wxGetApp().getScopeProcessor()->setScopeEnabled(scopeCanvas->scopeVisible());
|
||||
wxGetApp().getScopeProcessor()->setSpectrumEnabled(scopeCanvas->spectrumVisible());
|
||||
wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0));
|
||||
|
||||
wxGetApp().getScopeProcessor()->run();
|
||||
}
|
||||
|
||||
scopeCanvas->setShowDb(spectrumCanvas->getShowDb());
|
||||
wxGetApp().getScopeProcessor()->setScopeEnabled(scopeCanvas->scopeVisible());
|
||||
wxGetApp().getScopeProcessor()->setSpectrumEnabled(scopeCanvas->spectrumVisible());
|
||||
wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0));
|
||||
|
||||
wxGetApp().getScopeProcessor()->run();
|
||||
|
||||
SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcessor();
|
||||
|
||||
if (spectrumAvgMeter->inputChanged()) {
|
||||
@@ -1505,9 +1620,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
}
|
||||
|
||||
SpectrumVisualProcessor *dproc = wxGetApp().getDemodSpectrumProcessor();
|
||||
|
||||
dproc->setView(demodWaterfallCanvas->getViewState(), demodWaterfallCanvas->getCenterFrequency(),demodWaterfallCanvas->getBandwidth());
|
||||
|
||||
if (dproc) {
|
||||
dproc->setView(demodWaterfallCanvas->getViewState(), demodWaterfallCanvas->getCenterFrequency(),demodWaterfallCanvas->getBandwidth());
|
||||
}
|
||||
|
||||
SpectrumVisualProcessor *wproc = waterfallDataThread->getProcessor();
|
||||
|
||||
if (waterfallSpeedMeter->inputChanged()) {
|
||||
@@ -1539,13 +1656,15 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)demod->getOutput();
|
||||
if (!outp->getDialog()) {
|
||||
outp->setTitle(demod->getDemodulatorType() + ": " + frequencyToStr(demod->getFrequency()));
|
||||
outp->setDialog(new DigitalConsole(this, outp));
|
||||
outp->setDialog(new DigitalConsole(this, outp)) ;
|
||||
}
|
||||
demod->showOutput();
|
||||
}
|
||||
#endif
|
||||
} else if (!demod) {
|
||||
modemProps->Hide();
|
||||
} else if (!demod && modemPropertiesUpdated.load()) {
|
||||
ModemArgInfoList dummyInfo;
|
||||
modemProps->initProperties(dummyInfo, nullptr);
|
||||
modemProps->updateTheme();
|
||||
demodTray->Layout();
|
||||
}
|
||||
|
||||
@@ -1566,7 +1685,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
wxGetApp().getSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
|
||||
//make the peak hold act on the current dmod also, like a zoomed-in version.
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
|
||||
peakHoldButton->clearModeChanged();
|
||||
}
|
||||
|
||||
@@ -1580,7 +1699,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (scopeCanvas->HasFocus()) {
|
||||
if (scopeCanvas && scopeCanvas->HasFocus()) {
|
||||
waterfallCanvas->SetFocus();
|
||||
}
|
||||
#endif
|
||||
@@ -1652,35 +1771,10 @@ void AppFrame::saveSession(std::string fileName) {
|
||||
DataNode *demods = s.rootNode()->newChild("demodulators");
|
||||
|
||||
std::vector<DemodulatorInstance *> &instances = wxGetApp().getDemodMgr().getDemodulators();
|
||||
std::vector<DemodulatorInstance *>::iterator instance_i;
|
||||
for (instance_i = instances.begin(); instance_i != instances.end(); instance_i++) {
|
||||
|
||||
for (auto instance_i : instances) {
|
||||
DataNode *demod = demods->newChild("demodulator");
|
||||
*demod->newChild("bandwidth") = (*instance_i)->getBandwidth();
|
||||
*demod->newChild("frequency") = (*instance_i)->getFrequency();
|
||||
*demod->newChild("type") = (*instance_i)->getDemodulatorType();
|
||||
|
||||
demod->newChild("user_label")->element()->set((*instance_i)->getDemodulatorUserLabel());
|
||||
|
||||
*demod->newChild("squelch_level") = (*instance_i)->getSquelchLevel();
|
||||
*demod->newChild("squelch_enabled") = (*instance_i)->isSquelchEnabled() ? 1 : 0;
|
||||
*demod->newChild("output_device") = outputDevices[(*instance_i)->getOutputDevice()].name;
|
||||
*demod->newChild("gain") = (*instance_i)->getGain();
|
||||
*demod->newChild("muted") = (*instance_i)->isMuted() ? 1 : 0;
|
||||
if ((*instance_i)->isDeltaLock()) {
|
||||
*demod->newChild("delta_lock") = (*instance_i)->isDeltaLock() ? 1 : 0;
|
||||
*demod->newChild("delta_ofs") = (*instance_i)->getDeltaLockOfs();
|
||||
}
|
||||
if ((*instance_i) == wxGetApp().getDemodMgr().getLastActiveDemodulator()) {
|
||||
*demod->newChild("active") = 1;
|
||||
}
|
||||
|
||||
ModemSettings saveSettings = (*instance_i)->readModemSettings();
|
||||
if (saveSettings.size()) {
|
||||
DataNode *settingsNode = demod->newChild("settings");
|
||||
for (ModemSettings::const_iterator msi = saveSettings.begin(); msi != saveSettings.end(); msi++) {
|
||||
*settingsNode->newChild(msi->first.c_str()) = msi->second;
|
||||
}
|
||||
}
|
||||
wxGetApp().getDemodMgr().saveInstance(demod, instance_i);
|
||||
} //end for demodulators
|
||||
|
||||
// Make sure the file name actually ends in .xml
|
||||
@@ -1754,7 +1848,6 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
|
||||
DataNode *demodulators = l.rootNode()->getNext("demodulators");
|
||||
|
||||
int numDemodulators = 0;
|
||||
std::vector<DemodulatorInstance *> demodsLoaded;
|
||||
|
||||
while (demodulators->hasAnother("demodulator")) {
|
||||
@@ -1764,122 +1857,15 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long bandwidth = *demod->getNext("bandwidth");
|
||||
long long freq = *demod->getNext("frequency");
|
||||
float squelch_level = demod->hasAnother("squelch_level") ? (float) *demod->getNext("squelch_level") : 0;
|
||||
int squelch_enabled = demod->hasAnother("squelch_enabled") ? (int) *demod->getNext("squelch_enabled") : 0;
|
||||
int muted = demod->hasAnother("muted") ? (int) *demod->getNext("muted") : 0;
|
||||
int delta_locked = demod->hasAnother("delta_lock") ? (int) *demod->getNext("delta_lock") : 0;
|
||||
int delta_ofs = demod->hasAnother("delta_ofs") ? (int) *demod->getNext("delta_ofs") : 0;
|
||||
std::string output_device = demod->hasAnother("output_device") ? string(*(demod->getNext("output_device"))) : "";
|
||||
float gain = demod->hasAnother("gain") ? (float) *demod->getNext("gain") : 1.0;
|
||||
newDemod = wxGetApp().getDemodMgr().loadInstance(demod);
|
||||
|
||||
std::string type = "FM";
|
||||
|
||||
|
||||
DataNode *demodTypeNode = demod->hasAnother("type")?demod->getNext("type"):nullptr;
|
||||
|
||||
if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_INT) {
|
||||
int legacyType = *demodTypeNode;
|
||||
int legacyStereo = demod->hasAnother("stereo") ? (int) *demod->getNext("stereo") : 0;
|
||||
switch (legacyType) { // legacy demod ID
|
||||
case 1: type = legacyStereo?"FMS":"FM"; break;
|
||||
case 2: type = "AM"; break;
|
||||
case 3: type = "LSB"; break;
|
||||
case 4: type = "USB"; break;
|
||||
case 5: type = "DSB"; break;
|
||||
case 6: type = "ASK"; break;
|
||||
case 7: type = "APSK"; break;
|
||||
case 8: type = "BPSK"; break;
|
||||
case 9: type = "DPSK"; break;
|
||||
case 10: type = "PSK"; break;
|
||||
case 11: type = "OOK"; break;
|
||||
case 12: type = "ST"; break;
|
||||
case 13: type = "SQAM"; break;
|
||||
case 14: type = "QAM"; break;
|
||||
case 15: type = "QPSK"; break;
|
||||
case 16: type = "I/Q"; break;
|
||||
default: type = "FM"; break;
|
||||
}
|
||||
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_STRING) {
|
||||
demodTypeNode->element()->get(type);
|
||||
}
|
||||
|
||||
//read the user label associated with the demodulator
|
||||
std::wstring user_label = L"";
|
||||
|
||||
DataNode *demodUserLabel = demod->hasAnother("user_label") ? demod->getNext("user_label") : nullptr;
|
||||
|
||||
if (demodUserLabel) {
|
||||
|
||||
demodUserLabel->element()->get(user_label);
|
||||
}
|
||||
|
||||
|
||||
ModemSettings mSettings;
|
||||
|
||||
if (demod->hasAnother("settings")) {
|
||||
DataNode *modemSettings = demod->getNext("settings");
|
||||
for (int msi = 0, numSettings = modemSettings->numChildren(); msi < numSettings; msi++) {
|
||||
DataNode *settingNode = modemSettings->child(msi);
|
||||
std::string keyName = settingNode->getName();
|
||||
std::string strSettingValue = settingNode->element()->toString();
|
||||
|
||||
if (keyName != "" && strSettingValue != "") {
|
||||
mSettings[keyName] = strSettingValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
newDemod = wxGetApp().getDemodMgr().newThread();
|
||||
|
||||
if (demod->hasAnother("active")) {
|
||||
loadedActiveDemod = newDemod;
|
||||
}
|
||||
|
||||
numDemodulators++;
|
||||
newDemod->setDemodulatorType(type);
|
||||
newDemod->setDemodulatorUserLabel(user_label);
|
||||
newDemod->writeModemSettings(mSettings);
|
||||
newDemod->setBandwidth(bandwidth);
|
||||
newDemod->setFrequency(freq);
|
||||
newDemod->setGain(gain);
|
||||
newDemod->updateLabel(freq);
|
||||
newDemod->setMuted(muted?true:false);
|
||||
if (delta_locked) {
|
||||
newDemod->setDeltaLock(true);
|
||||
newDemod->setDeltaLockOfs(delta_ofs);
|
||||
}
|
||||
if (squelch_enabled) {
|
||||
newDemod->setSquelchEnabled(true);
|
||||
newDemod->setSquelchLevel(squelch_level);
|
||||
}
|
||||
|
||||
bool found_device = false;
|
||||
std::map<int, RtAudio::DeviceInfo>::iterator i;
|
||||
for (i = outputDevices.begin(); i != outputDevices.end(); i++) {
|
||||
if (i->second.name == output_device) {
|
||||
newDemod->setOutputDevice(i->first);
|
||||
found_device = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (!found_device) {
|
||||
// std::cout << "\tWarning: named output device '" << output_device << "' was not found. Using default output.";
|
||||
// }
|
||||
|
||||
newDemod->run();
|
||||
newDemod->setActive(true);
|
||||
demodsLoaded.push_back(newDemod);
|
||||
// wxGetApp().bindDemodulator(newDemod);
|
||||
|
||||
std::cout << "\tAdded demodulator at frequency " << newDemod->getFrequency() << " type " << type << std::endl;
|
||||
// std::cout << "\t\tBandwidth: " << bandwidth << std::endl;
|
||||
// std::cout << "\t\tSquelch Level: " << squelch_level << std::endl;
|
||||
// std::cout << "\t\tSquelch Enabled: " << (squelch_enabled ? "true" : "false") << std::endl;
|
||||
// std::cout << "\t\tOutput Device: " << output_device << std::endl;
|
||||
}
|
||||
|
||||
if (demodsLoaded.size()) {
|
||||
@@ -1925,6 +1911,8 @@ bool AppFrame::loadSession(std::string fileName) {
|
||||
GetStatusBar()->SetStatusText(wxString::Format(wxT("Loaded session file: %s"), currentSessionFile.c_str()));
|
||||
SetTitle(wxString::Format(wxT("%s: %s"), CUBICSDR_TITLE, filePart.c_str()));
|
||||
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1945,7 +1933,7 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) {
|
||||
}
|
||||
|
||||
void AppFrame::setScopeDeviceName(std::string deviceName) {
|
||||
scopeCanvas->setDeviceName(deviceName);
|
||||
if (scopeCanvas) scopeCanvas->setDeviceName(deviceName);
|
||||
}
|
||||
|
||||
|
||||
@@ -1957,12 +1945,20 @@ void AppFrame::refreshGainUI() {
|
||||
bool AppFrame::isUserDemodBusy() {
|
||||
return (modemProps && modemProps->isMouseInView())
|
||||
|| (waterfallCanvas->isMouseInView() && waterfallCanvas->isMouseDown())
|
||||
|| (demodWaterfallCanvas->isMouseInView() && demodWaterfallCanvas->isMouseDown())
|
||||
|| (demodWaterfallCanvas && demodWaterfallCanvas->isMouseInView() && demodWaterfallCanvas->isMouseDown())
|
||||
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() &&
|
||||
wxGetApp().getDemodMgr().getActiveDemodulator() &&
|
||||
wxGetApp().getDemodMgr().getLastActiveDemodulator() != wxGetApp().getDemodMgr().getActiveDemodulator());
|
||||
}
|
||||
|
||||
BookmarkView *AppFrame::getBookmarkView() {
|
||||
return bookmarkView;
|
||||
}
|
||||
|
||||
void AppFrame::disableSave(bool state) {
|
||||
saveDisabled = state;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
bool AppFrame::canFocus() {
|
||||
@@ -2022,6 +2018,10 @@ int AppFrame::OnGlobalKeyDown(wxKeyEvent &event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bookmarkView && bookmarkView->isMouseInView()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DemodulatorInstance *demod = nullptr, *lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
int snap = wxGetApp().getFrequencySnap();
|
||||
|
||||
@@ -2123,6 +2123,10 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bookmarkView && bookmarkView->isMouseInView()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event.ControlDown()) {
|
||||
return 1;
|
||||
}
|
||||
@@ -2195,7 +2199,7 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
|
||||
break;
|
||||
case 'P':
|
||||
wxGetApp().getSpectrumProcessor()->setPeakHold(!wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
|
||||
peakHoldButton->setSelection(wxGetApp().getSpectrumProcessor()->getPeakHold()?1:0);
|
||||
peakHoldButton->clearModeChanged();
|
||||
break;
|
||||
@@ -2246,3 +2250,42 @@ void AppFrame::setViewState(long long center_freq) {
|
||||
spectrumCanvas->disableView();
|
||||
waterfallCanvas->disableView();
|
||||
}
|
||||
|
||||
|
||||
long long AppFrame::getViewCenterFreq() {
|
||||
return waterfallCanvas->getCenterFrequency();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int AppFrame::getViewBandwidth() {
|
||||
return waterfallCanvas->getBandwidth();
|
||||
}
|
||||
|
||||
|
||||
/* split a string by 'seperator' into a vector of string */
|
||||
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str)
|
||||
{
|
||||
std::vector<std::string> vect_out;
|
||||
|
||||
int i = 0, j = 0;
|
||||
int seperator_len = seperator.length();
|
||||
int str_len = in_str.length();
|
||||
|
||||
while(i < str_len)
|
||||
{
|
||||
j = in_str.find_first_of(seperator,i);
|
||||
|
||||
if (j == std::string::npos && i < str_len) j = str_len;
|
||||
|
||||
if (j == std::string::npos) break;
|
||||
|
||||
vect_out.push_back(in_str.substr(i,j-i));
|
||||
|
||||
i = j;
|
||||
|
||||
i+=seperator_len;
|
||||
}
|
||||
|
||||
return vect_out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user