Merge pull request #572 from cjcliffe/vso_shared_ptr_DemodulatorInstances

Let's see if I've broken something :)
This commit is contained in:
Vincent Sonnier 2017-08-27 14:47:10 +02:00 committed by GitHub
commit 2d01a279e9
35 changed files with 351 additions and 392 deletions

View File

@ -1709,10 +1709,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
}
}
//try to garbage collect the retired demodulators.
wxGetApp().getDemodMgr().garbageCollect();
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (demod && demod->isModemInitialized()) {
if (demod->isTracking()) {
@ -2129,11 +2126,12 @@ void AppFrame::saveSession(std::string fileName) {
DataNode *demods = s.rootNode()->newChild("demodulators");
std::vector<DemodulatorInstance *> &instances = wxGetApp().getDemodMgr().getDemodulators();
//make a local copy snapshot of the list
std::vector<DemodulatorInstancePtr> instances = wxGetApp().getDemodMgr().getDemodulators();
for (auto instance_i : instances) {
for (auto instance : instances) {
DataNode *demod = demods->newChild("demodulator");
wxGetApp().getDemodMgr().saveInstance(demod, instance_i);
wxGetApp().getDemodMgr().saveInstance(demod, instance);
} //end for demodulators
// Make sure the file name actually ends in .xml
@ -2247,14 +2245,14 @@ bool AppFrame::loadSession(std::string fileName) {
wxGetApp().setSoloMode(false);
}
DemodulatorInstance *loadedActiveDemod = nullptr;
DemodulatorInstance *newDemod = nullptr;
DemodulatorInstancePtr loadedActiveDemod = nullptr;
DemodulatorInstancePtr newDemod = nullptr;
if (l.rootNode()->hasAnother("demodulators")) {
DataNode *demodulators = l.rootNode()->getNext("demodulators");
std::vector<DemodulatorInstance *> demodsLoaded;
std::vector<DemodulatorInstancePtr> demodsLoaded;
while (demodulators->hasAnother("demodulator")) {
DataNode *demod = demodulators->getNext("demodulator");
@ -2275,7 +2273,7 @@ bool AppFrame::loadSession(std::string fileName) {
}
if (demodsLoaded.size()) {
wxGetApp().bindDemodulators(&demodsLoaded);
wxGetApp().notifyDemodulatorsChanged();
}
} // if l.rootNode()->hasAnother("demodulators")
@ -2404,14 +2402,14 @@ FrequencyDialog::FrequencyDialogTarget AppFrame::getFrequencyDialogTarget() {
return target;
}
void AppFrame::gkNudgeLeft(DemodulatorInstance *demod, int snap) {
void AppFrame::gkNudgeLeft(DemodulatorInstancePtr demod, int snap) {
if (demod) {
demod->setFrequency(demod->getFrequency()-snap);
demod->updateLabel(demod->getFrequency());
}
}
void AppFrame::gkNudgeRight(DemodulatorInstance *demod, int snap) {
void AppFrame::gkNudgeRight(DemodulatorInstancePtr demod, int snap) {
if (demod) {
demod->setFrequency(demod->getFrequency()+snap);
demod->updateLabel(demod->getFrequency());
@ -2437,7 +2435,10 @@ int AppFrame::OnGlobalKeyDown(wxKeyEvent &event) {
return -1;
}
DemodulatorInstance *demod = nullptr, *lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr demod = nullptr;
DemodulatorInstancePtr lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
int snap = wxGetApp().getFrequencySnap();
if (event.ControlDown()) {
@ -2562,8 +2563,8 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
return 1;
}
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstance *lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstancePtr lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
#ifdef wxHAS_RAW_KEY_CODES
switch (event.GetRawKeyCode()) {

View File

@ -26,7 +26,8 @@
#include "FrequencyDialog.h"
#include "BookmarkView.h"
#include "AboutDialog.h"
#include "DemodulatorInstance.h"
#include "DemodulatorThread.h"
#include <map>
#define wxID_RT_AUDIO_DEVICE 1000
@ -107,8 +108,8 @@ public:
void setMainWaterfallFFTSize(int fftSize);
void setScopeDeviceName(std::string deviceName);
void gkNudgeLeft(DemodulatorInstance *demod, int snap);
void gkNudgeRight(DemodulatorInstance *demod, int snap);
void gkNudgeLeft(DemodulatorInstancePtr demod, int snap);
void gkNudgeRight(DemodulatorInstancePtr demod, int snap);
int OnGlobalKeyDown(wxKeyEvent &event);
int OnGlobalKeyUp(wxKeyEvent &event);
@ -193,7 +194,7 @@ private:
wxBoxSizer *demodTray;
BookmarkView *bookmarkView;
DemodulatorInstance *activeDemodulator;
DemodulatorInstancePtr activeDemodulator;
std::vector<RtAudio::DeviceInfo> devices;
std::map<int,RtAudio::DeviceInfo> inputDevices;

View File

@ -205,7 +205,7 @@ bool BookmarkMgr::hasBackup(std::string bookmarkFn) {
return backupFile.FileExists() && backupFile.IsFileReadable();
}
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstance *demod) {
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstancePtr demod) {
std::lock_guard < std::recursive_mutex > lock(busy_lock);
//Create a BookmarkEntry from demod data, saving its
@ -392,7 +392,7 @@ void BookmarkMgr::updateBookmarks(std::string group) {
}
void BookmarkMgr::addRecent(DemodulatorInstance *demod) {
void BookmarkMgr::addRecent(DemodulatorInstancePtr demod) {
std::lock_guard < std::recursive_mutex > lock(busy_lock);
recents.push_back(demodToBookmarkEntry(demod));
@ -482,7 +482,7 @@ void BookmarkMgr::clearRanges() {
}
BookmarkEntryPtr BookmarkMgr::demodToBookmarkEntry(DemodulatorInstance *demod) {
BookmarkEntryPtr BookmarkMgr::demodToBookmarkEntry(DemodulatorInstancePtr demod) {
BookmarkEntryPtr be(new BookmarkEntry);
@ -536,7 +536,7 @@ std::wstring BookmarkMgr::getBookmarkEntryDisplayName(BookmarkEntryPtr bmEnt) {
return dispName;
}
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstance *demod) {
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstancePtr demod) {
std::wstring activeName = demod->getDemodulatorUserLabel();
if (activeName == "") {
@ -547,7 +547,7 @@ std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstance *demod) {
return activeName;
}
void BookmarkMgr::removeActive(DemodulatorInstance *demod) {
void BookmarkMgr::removeActive(DemodulatorInstancePtr demod) {
std::lock_guard < std::recursive_mutex > lock(busy_lock);

View File

@ -85,7 +85,7 @@ public:
bool hasLastLoad(std::string bookmarkFn);
bool hasBackup(std::string bookmarkFn);
void addBookmark(std::string group, DemodulatorInstance *demod);
void addBookmark(std::string group, DemodulatorInstancePtr demod);
void addBookmark(std::string group, BookmarkEntryPtr be);
void removeBookmark(std::string group, BookmarkEntryPtr be);
void removeBookmark(BookmarkEntryPtr be);
@ -105,13 +105,13 @@ public:
void updateBookmarks();
void updateBookmarks(std::string group);
void addRecent(DemodulatorInstance *demod);
void addRecent(DemodulatorInstancePtr demod);
void addRecent(BookmarkEntryPtr be);
void removeRecent(BookmarkEntryPtr be);
const BookmarkList& getRecents();
void clearRecents();
void removeActive(DemodulatorInstance *demod);
void removeActive(DemodulatorInstancePtr demod);
void addRange(BookmarkRangeEntryPtr re);
void removeRange(BookmarkRangeEntryPtr re);
@ -119,13 +119,13 @@ public:
void clearRanges();
static std::wstring getBookmarkEntryDisplayName(BookmarkEntryPtr bmEnt);
static std::wstring getActiveDisplayName(DemodulatorInstance *demod);
static std::wstring getActiveDisplayName(DemodulatorInstancePtr demod);
protected:
void trimRecents();
BookmarkEntryPtr demodToBookmarkEntry(DemodulatorInstance *demod);
BookmarkEntryPtr demodToBookmarkEntry(DemodulatorInstancePtr demod);
BookmarkEntryPtr nodeToBookmark(DataNode *node);
BookmarkMap bmData;

View File

@ -421,9 +421,6 @@ int CubicSDR::OnExit() {
std::cout << "Terminating All Demodulators.." << std::endl << std::flush;
demodMgr.terminateAll();
//wait for effective death of all demodulators before continuing.
terminationSequenceOK = terminationSequenceOK && demodMgr.garbageCollect(true, 3000);
std::cout << "Terminating Visual Processor threads.." << std::endl << std::flush;
spectrumVisualThread->terminate();
if (demodVisualThread) {
@ -831,30 +828,21 @@ SDRThread *CubicSDR::getSDRThread() {
}
void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
sdrPostThread->bindDemodulator(demod);
}
void CubicSDR::bindDemodulators(std::vector<DemodulatorInstance *> *demods) {
if (!demods) {
return;
}
sdrPostThread->bindDemodulators(demods);
void CubicSDR::notifyDemodulatorsChanged() {
sdrPostThread->notifyDemodulatorsChanged();
}
long long CubicSDR::getSampleRate() {
return sampleRate;
}
void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
void CubicSDR::removeDemodulator(DemodulatorInstancePtr demod) {
if (!demod) {
return;
}
demod->setActive(false);
sdrPostThread->removeDemodulator(demod);
sdrPostThread->notifyDemodulatorsChanged();
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
}
@ -926,7 +914,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
void CubicSDR::showLabelInput() {
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
if (activeDemod != nullptr) {

View File

@ -121,9 +121,9 @@ public:
SDRPostThread *getSDRPostThread();
SDRThread *getSDRThread();
void bindDemodulator(DemodulatorInstance *demod);
void bindDemodulators(std::vector<DemodulatorInstance *> *demods);
void removeDemodulator(DemodulatorInstance *demod);
void notifyDemodulatorsChanged();
void removeDemodulator(DemodulatorInstancePtr demod);
void setFrequencySnap(int snap);
int getFrequencySnap();

View File

@ -13,7 +13,7 @@ EVT_SHOW(DemodLabelDialog::OnShow)
wxEND_EVENT_TABLE()
DemodLabelDialog::DemodLabelDialog(wxWindow * parent, wxWindowID id, const wxString & title,
DemodulatorInstance *demod, const wxPoint & position,
DemodulatorInstancePtr demod, const wxPoint & position,
const wxSize & size, long style) :
wxDialog(parent, id, title, position, size, style) {

View File

@ -16,7 +16,7 @@ class DemodLabelDialog : public wxDialog
public:
DemodLabelDialog( wxWindow * parent, wxWindowID id, const wxString & title,
DemodulatorInstance *demod = NULL,
DemodulatorInstancePtr demod = nullptr,
const wxPoint & pos = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = wxDEFAULT_DIALOG_STYLE);
@ -24,7 +24,7 @@ public:
wxTextCtrl * dialogText;
private:
DemodulatorInstance *activeDemod = nullptr;
DemodulatorInstancePtr activeDemod = nullptr;
void OnEnter ( wxCommandEvent &event );
void OnChar ( wxKeyEvent &event );
void OnShow(wxShowEvent &event);

View File

@ -12,11 +12,13 @@ EVT_CHAR_HOOK(FrequencyDialog::OnChar)
EVT_SHOW(FrequencyDialog::OnShow)
wxEND_EVENT_TABLE()
FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position,
FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstancePtr demod, const wxPoint & position,
const wxSize & size, long style, FrequencyDialogTarget targetMode, wxString initString) :
wxDialog(parent, id, title, position, size, style) {
wxString freqStr;
activeDemod = demod;
this->targetMode = targetMode;
this->initialString = initString;

View File

@ -24,7 +24,7 @@ public:
FDIALOG_TARGET_GAIN
} FrequencyDialogTarget;
FrequencyDialog ( wxWindow * parent, wxWindowID id, const wxString & title,
DemodulatorInstance *demod = NULL,
DemodulatorInstancePtr demod = nullptr,
const wxPoint & pos = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = wxDEFAULT_DIALOG_STYLE,
@ -34,7 +34,7 @@ public:
wxTextCtrl * dialogText;
private:
DemodulatorInstance *activeDemod;
DemodulatorInstancePtr activeDemod;
void OnEnter ( wxCommandEvent &event );
void OnChar ( wxKeyEvent &event );
void OnShow(wxShowEvent &event);

View File

@ -101,7 +101,7 @@ void ModemProperties::initDefaultProperties() {
defaultProps["._audio_output"] = addArgInfoProperty(m_propertyGrid, outputArg);
}
void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstance *demodInstance) {
void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstancePtr demodInstance) {
args = newArgs;
demodContext = demodInstance;

View File

@ -24,7 +24,7 @@ public:
~ModemProperties();
void initDefaultProperties();
void initProperties(ModemArgInfoList newArgs, DemodulatorInstance *demodInstance);
void initProperties(ModemArgInfoList newArgs, DemodulatorInstancePtr demodInstance);
bool isMouseInView();
void setCollapsed(bool state);
bool isCollapsed();
@ -46,7 +46,8 @@ private:
wxBoxSizer* bSizer;
wxPropertyGrid* m_propertyGrid;
ModemArgInfoList args;
DemodulatorInstance *demodContext;
DemodulatorInstancePtr demodContext;
std::map<std::string, wxPGProperty *> props;
bool mouseInView, collapsed;

View File

@ -304,14 +304,12 @@ void AudioThread::setSampleRate(int sampleRate) {
srcmix->setSampleRate(sampleRate);
}
std::vector<DemodulatorInstance *>::iterator demod_i;
std::vector<DemodulatorInstance *> *demodulators;
//make a local copy, snapshot of the list of demodulators
std::vector<DemodulatorInstancePtr> demodulators = wxGetApp().getDemodMgr().getDemodulators();
demodulators = &wxGetApp().getDemodMgr().getDemodulators();
for (demod_i = demodulators->begin(); demod_i != demodulators->end(); demod_i++) {
if ((*demod_i)->getOutputDevice() == outputDevice.load()) {
(*demod_i)->setAudioSampleRate(sampleRate);
for (auto demod : demodulators) {
if (demod->getOutputDevice() == outputDevice.load()) {
demod->setAudioSampleRate(sampleRate);
}
}

View File

@ -35,6 +35,10 @@ public:
typedef std::shared_ptr<AudioThreadInput> AudioThreadInputPtr;
typedef ThreadBlockingQueue<AudioThreadInputPtr> DemodulatorThreadOutputQueue;
typedef std::shared_ptr<DemodulatorThreadOutputQueue> DemodulatorThreadOutputQueuePtr;
class AudioThreadCommand {
public:
enum AudioThreadCommandEnum {

View File

@ -15,7 +15,6 @@
class DemodulatorThread;
class DemodulatorThreadControlCommand {
public:
enum DemodulatorThreadControlCommandEnum {

View File

@ -5,6 +5,10 @@
#include "DemodulatorInstance.h"
#include "CubicSDR.h"
#include "DemodulatorThread.h"
#include "DemodulatorPreThread.h"
#if USE_HAMLIB
#include "RigThread.h"
#endif
@ -79,13 +83,37 @@ DemodulatorInstance::DemodulatorInstance() {
}
DemodulatorInstance::~DemodulatorInstance() {
std::lock_guard < std::mutex > lockData(m_thread_control_mutex);
std::lock_guard < std::recursive_mutex > lockData(m_thread_control_mutex);
//now that DemodulatorInstance are managed through shared_ptr, we
//should enter here ONLY when it is no longer used by any piece of code, anywhere.
//so active wait on IsTerminated(), then die.
#define TERMINATION_SPIN_WAIT_MS (20)
#define MAX_WAIT_FOR_TERMINATION_MS (3000.0)
//this is a stupid busy plus sleep loop
int nbCyclesToWait = (MAX_WAIT_FOR_TERMINATION_MS / TERMINATION_SPIN_WAIT_MS) + 1;
int currentCycle = 0;
while (currentCycle < nbCyclesToWait) {
if (isTerminated()) {
std::cout << "Garbage collected demodulator instance '" << getLabel() << "'... " << std::endl << std::flush;
#if ENABLE_DIGITAL_LAB
delete activeOutput;
delete activeOutput;
#endif
delete audioThread;
delete demodulatorThread;
delete demodulatorPreThread;
delete audioThread;
delete demodulatorThread;
delete demodulatorPreThread;
break;
}
else {
std::this_thread::sleep_for(std::chrono::milliseconds(TERMINATION_SPIN_WAIT_MS));
}
currentCycle++;
} //end while
}
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueuePtr tQueue) {
@ -94,7 +122,7 @@ void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueuePtr t
void DemodulatorInstance::run() {
std::lock_guard < std::mutex > lockData(m_thread_control_mutex);
std::lock_guard < std::recursive_mutex > lockData(m_thread_control_mutex);
if (active) {
return;
@ -163,7 +191,7 @@ void DemodulatorInstance::setLabel(std::string labelStr) {
bool DemodulatorInstance::isTerminated() {
std::lock_guard < std::mutex > lockData(m_thread_control_mutex);
std::lock_guard < std::recursive_mutex > lockData(m_thread_control_mutex);
bool audioTerminated = audioThread->isTerminated();
bool demodTerminated = demodulatorThread->isTerminated();
@ -224,7 +252,9 @@ void DemodulatorInstance::setActive(bool state) {
}
#endif
audioThread->setActive(state);
DemodulatorThread::releaseSquelchLock(this);
} else if (!active && state) {
#if ENABLE_DIGITAL_LAB
if (activeOutput && getModemType() == "digital") {
@ -404,7 +434,7 @@ void DemodulatorInstance::setFrequency(long long freq) {
}
#endif
#if USE_HAMLIB
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && wxGetApp().getDemodMgr().getLastActiveDemodulator() == this) {
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && wxGetApp().getDemodMgr().getLastActiveDemodulator().get() == this) {
wxGetApp().getRigThread()->setFrequency(freq,true);
}
#endif

View File

@ -6,12 +6,11 @@
#include <vector>
#include <map>
#include <thread>
#include "DemodulatorThread.h"
#include "DemodulatorPreThread.h"
#include <memory>
#include "DemodDefs.h"
#include "ModemDigital.h"
#include "ModemAnalog.h"
#include "AudioThread.h"
#if ENABLE_DIGITAL_LAB
#include "DigitalConsole.h"
@ -30,6 +29,8 @@ private:
std::atomic_int squelchBreak;
};
class DemodulatorThread;
class DemodulatorPreThread;
class DemodulatorInstance {
public:
@ -139,7 +140,7 @@ private:
DemodulatorThreadControlCommandQueuePtr threadQueueControl;
//protects child thread creation and termination
std::mutex m_thread_control_mutex;
std::recursive_mutex m_thread_control_mutex;
std::atomic<std::string *> label; //
// User editable buffer, 16 bit string.
@ -161,3 +162,5 @@ private:
ModemDigitalOutput *activeOutput;
#endif
};
typedef std::shared_ptr<DemodulatorInstance> DemodulatorInstancePtr;

View File

@ -17,13 +17,11 @@
#include "DataTree.h"
bool demodFreqCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->getFrequency()<j->getFrequency()); }
bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->isActive()<j->isActive()); }
bool demodFreqCompare (DemodulatorInstancePtr i, DemodulatorInstancePtr j) { return (i->getFrequency() < j->getFrequency()); }
bool inactiveCompare (DemodulatorInstancePtr i, DemodulatorInstancePtr j) { return (i->isActive() < j->isActive()); }
DemodulatorMgr::DemodulatorMgr() {
activeDemodulator = NULL;
lastActiveDemodulator = NULL;
activeVisualDemodulator = NULL;
lastBandwidth = DEFAULT_DEMOD_BW;
lastDemodType = DEFAULT_DEMOD_TYPE;
lastSquelchEnabled = false;
@ -37,9 +35,11 @@ DemodulatorMgr::~DemodulatorMgr() {
terminateAll();
}
DemodulatorInstance *DemodulatorMgr::newThread() {
DemodulatorInstancePtr DemodulatorMgr::newThread() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
DemodulatorInstance *newDemod = new DemodulatorInstance;
//create a new instance of DemodulatorInstance here.
DemodulatorInstancePtr newDemod = std::make_shared<DemodulatorInstance>();
std::stringstream label;
label << demods.size();
@ -51,27 +51,34 @@ DemodulatorInstance *DemodulatorMgr::newThread() {
}
void DemodulatorMgr::terminateAll() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
while (demods.size()) {
DemodulatorInstance *d = demods.back();
DemodulatorInstancePtr d = demods.back();
demods.pop_back();
wxGetApp().removeDemodulator(d);
deleteThread(d);
}
}
std::vector<DemodulatorInstance *> &DemodulatorMgr::getDemodulators() {
std::vector<DemodulatorInstancePtr> DemodulatorMgr::getDemodulators() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
return demods;
}
std::vector<DemodulatorInstance *> DemodulatorMgr::getOrderedDemodulators(bool actives) {
std::vector<DemodulatorInstancePtr> DemodulatorMgr::getOrderedDemodulators(bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = demods;
auto demods_ordered = demods;
if (actives) {
std::sort(demods_ordered.begin(), demods_ordered.end(), inactiveCompare);
std::vector<DemodulatorInstance *>::iterator i;
std::vector<DemodulatorInstancePtr>::iterator i;
for (i = demods_ordered.begin(); i != demods_ordered.end(); i++) {
if ((*i)->isActive()) {
break;
@ -88,13 +95,14 @@ std::vector<DemodulatorInstance *> DemodulatorMgr::getOrderedDemodulators(bool a
return demods_ordered;
}
DemodulatorInstance *DemodulatorMgr::getPreviousDemodulator(DemodulatorInstance *demod, bool actives) {
DemodulatorInstancePtr DemodulatorMgr::getPreviousDemodulator(DemodulatorInstancePtr demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) {
return nullptr;
}
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators(actives);
std::vector<DemodulatorInstance *>::iterator p = std::find(demods_ordered.begin(), demods_ordered.end(), demod);
auto demods_ordered = getOrderedDemodulators(actives);
auto p = std::find(demods_ordered.begin(), demods_ordered.end(), demod);
if (p == demods_ordered.end()) {
return nullptr;
}
@ -104,13 +112,14 @@ DemodulatorInstance *DemodulatorMgr::getPreviousDemodulator(DemodulatorInstance
return *(--p);
}
DemodulatorInstance *DemodulatorMgr::getNextDemodulator(DemodulatorInstance *demod, bool actives) {
DemodulatorInstancePtr DemodulatorMgr::getNextDemodulator(DemodulatorInstancePtr demod, bool actives) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!getLastActiveDemodulator()) {
return nullptr;
}
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators(actives);
std::vector<DemodulatorInstance *>::iterator p = std::find(demods_ordered.begin(), demods_ordered.end(), demod);
auto demods_ordered = getOrderedDemodulators(actives);
auto p = std::find(demods_ordered.begin(), demods_ordered.end(), demod);
if (actives) {
}
@ -123,26 +132,25 @@ DemodulatorInstance *DemodulatorMgr::getNextDemodulator(DemodulatorInstance *dem
return *(++p);
}
DemodulatorInstance *DemodulatorMgr::getLastDemodulator() {
DemodulatorInstancePtr DemodulatorMgr::getLastDemodulator() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators();
return *(demods_ordered.end());
return getOrderedDemodulators().back();
}
DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() {
DemodulatorInstancePtr DemodulatorMgr::getFirstDemodulator() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> demods_ordered = getOrderedDemodulators();
return *(demods_ordered.begin());
return getOrderedDemodulators().front();
}
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
void DemodulatorMgr::deleteThread(DemodulatorInstancePtr demod) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
wxGetApp().getBookmarkMgr().addRecent(demod);
std::vector<DemodulatorInstance *>::iterator i;
i = std::find(demods.begin(), demods.end(), demod);
auto i = std::find(demods.begin(), demods.end(), demod);
if (activeDemodulator == demod) {
activeDemodulator = nullptr;
@ -161,19 +169,15 @@ void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
//Ask for termination
demod->setActive(false);
demod->terminate();
//Do not cleanup immediatly
std::lock_guard < std::mutex > lock_deleted(deleted_demods_busy);
demods_deleted.push_back(demod);
}
std::vector<DemodulatorInstance *> DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) {
std::vector<DemodulatorInstancePtr> DemodulatorMgr::getDemodulatorsAt(long long freq, int bandwidth) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
std::vector<DemodulatorInstance *> foundDemods;
std::vector<DemodulatorInstancePtr> foundDemods;
for (int i = 0, iMax = demods.size(); i < iMax; i++) {
DemodulatorInstance *testDemod = demods[i];
DemodulatorInstancePtr testDemod = demods[i];
long long freqTest = testDemod->getFrequency();
long long bandwidthTest = testDemod->getBandwidth();
@ -192,7 +196,7 @@ std::vector<DemodulatorInstance *> DemodulatorMgr::getDemodulatorsAt(long long f
bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
for (int i = 0, iMax = demods.size(); i < iMax; i++) {
DemodulatorInstance *testDemod = demods[i];
DemodulatorInstancePtr testDemod = demods[i];
long long freqTest = testDemod->getFrequency();
long long bandwidthTest = testDemod->getBandwidth();
@ -210,32 +214,34 @@ bool DemodulatorMgr::anyDemodulatorsAt(long long freq, int bandwidth) {
}
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool temporary) {
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstancePtr demod, bool temporary) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (!temporary) {
if (activeDemodulator.load() != nullptr) {
lastActiveDemodulator = activeDemodulator.load();
if (activeDemodulator != nullptr) {
lastActiveDemodulator = activeDemodulator;
updateLastState();
} else {
lastActiveDemodulator = demod;
}
updateLastState();
#if USE_HAMLIB
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && lastActiveDemodulator.load()) {
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator.load()->getFrequency(),true);
if (wxGetApp().rigIsActive() && wxGetApp().getRigThread()->getFollowModem() && lastActiveDemodulator) {
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator->getFrequency(),true);
}
#endif
wxGetApp().getBookmarkMgr().updateActiveList();
}
if (activeVisualDemodulator.load()) {
activeVisualDemodulator.load()->setVisualOutputQueue(nullptr);
if (activeVisualDemodulator) {
activeVisualDemodulator->setVisualOutputQueue(nullptr);
}
if (demod) {
demod->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
activeVisualDemodulator = demod;
} else {
DemodulatorInstance *last = getLastActiveDemodulator();
DemodulatorInstancePtr last = getLastActiveDemodulator();
if (last) {
last->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
}
@ -246,25 +252,41 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
}
DemodulatorInstance *DemodulatorMgr::getActiveDemodulator() {
if (activeDemodulator.load() && !activeDemodulator.load()->isActive()) {
//Dangerous: this is only intended by some internal classes
void DemodulatorMgr::setActiveDemodulatorByRawPointer(DemodulatorInstance* demod, bool temporary) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
for (auto existing_demod : demods) {
if (existing_demod.get() == demod) {
setActiveDemodulator(existing_demod, temporary);
break;
}
}
}
DemodulatorInstancePtr DemodulatorMgr::getActiveDemodulator() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (activeDemodulator && !activeDemodulator->isActive()) {
activeDemodulator = getLastActiveDemodulator();
}
return activeDemodulator;
}
DemodulatorInstance *DemodulatorMgr::getLastActiveDemodulator() {
DemodulatorInstancePtr DemodulatorMgr::getLastActiveDemodulator() {
return lastActiveDemodulator;
}
DemodulatorInstance *DemodulatorMgr::getLastDemodulatorWith(const std::string& type,
DemodulatorInstancePtr DemodulatorMgr::getLastDemodulatorWith(const std::string& type,
const std::wstring& userLabel,
long long frequency,
int bandwidth) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
//backwards search:
for (std::vector<DemodulatorInstance *>::reverse_iterator it = demods.rbegin(); it != demods.rend(); it++) {
for (auto it = demods.rbegin(); it != demods.rend(); it++) {
if ((*it)->getDemodulatorType() == type &&
(*it)->getDemodulatorUserLabel() == userLabel &&
@ -278,86 +300,31 @@ DemodulatorInstance *DemodulatorMgr::getLastDemodulatorWith(const std::string& t
return nullptr;
}
bool DemodulatorMgr::garbageCollect(bool forcedGC, int maxWaitForTerminationMs) {
#define SPIN_WAIT_SLEEP_MS 5
//this is a stupid busy plus sleep loop
int nbCyclesToWait = 0;
if (maxWaitForTerminationMs <= 0) {
nbCyclesToWait = std::numeric_limits<int>::max();
}
else {
nbCyclesToWait = (maxWaitForTerminationMs / SPIN_WAIT_SLEEP_MS) + 1;
}
int currentWaitCycle = 0;
std::lock_guard < std::mutex > lock(deleted_demods_busy);
while (!demods_deleted.empty()) {
std::vector<DemodulatorInstance *>::iterator it = demods_deleted.begin();
//make 1 pass over
while (it != demods_deleted.end()) {
if ((*it)->isTerminated()) {
DemodulatorInstance *deleted = (*it);
std::cout << "Garbage collected demodulator instance '" << deleted->getLabel() << "'... " << std::endl << std::flush;
it = demods_deleted.erase(it);
delete deleted;
//only garbage collect 1 demod at a time.
if (!forcedGC) {
return true;
}
}
else {
it++;
}
} //end while
//stupid busy-wait loop
std::this_thread::sleep_for(std::chrono::milliseconds(SPIN_WAIT_SLEEP_MS));
currentWaitCycle++;
if (currentWaitCycle >= nbCyclesToWait) {
std::cout << "ERROR: DemodulatorMgr::garbageCollect() has not terminated in time ! (> " << (currentWaitCycle * SPIN_WAIT_SLEEP_MS) << " ms)" << std::endl << std::flush;
return false;
}
} //end while not empty
return true;
}
void DemodulatorMgr::updateLastState() {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) {
if (activeDemodulator.load() && activeDemodulator.load()->isActive()) {
lastActiveDemodulator = activeDemodulator.load();
} else if (activeDemodulator.load() && !activeDemodulator.load()->isActive()){
if (activeDemodulator && activeDemodulator->isActive()) {
lastActiveDemodulator = activeDemodulator;
} else if (activeDemodulator && !activeDemodulator->isActive()){
activeDemodulator = nullptr;
lastActiveDemodulator = nullptr;
}
}
if (lastActiveDemodulator.load() && !lastActiveDemodulator.load()->isActive()) {
if (lastActiveDemodulator && !lastActiveDemodulator->isActive()) {
lastActiveDemodulator = nullptr;
}
if (lastActiveDemodulator.load()) {
lastBandwidth = lastActiveDemodulator.load()->getBandwidth();
lastDemodType = lastActiveDemodulator.load()->getDemodulatorType();
lastDemodLock = lastActiveDemodulator.load()->getDemodulatorLock()?true:false;
lastSquelchEnabled = lastActiveDemodulator.load()->isSquelchEnabled();
lastSquelch = lastActiveDemodulator.load()->getSquelchLevel();
lastGain = lastActiveDemodulator.load()->getGain();
lastModemSettings[lastDemodType] = lastActiveDemodulator.load()->readModemSettings();
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();
}
}
@ -436,7 +403,8 @@ void DemodulatorMgr::setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs) {
outputDevices = devs;
}
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstance *inst) {
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstancePtr inst) {
*node->newChild("bandwidth") = inst->getBandwidth();
*node->newChild("frequency") = inst->getFrequency();
*node->newChild("type") = inst->getDemodulatorType();
@ -465,11 +433,11 @@ void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstance *inst) {
}
}
DemodulatorInstance *DemodulatorMgr::loadInstance(DataNode *node) {
DemodulatorInstancePtr DemodulatorMgr::loadInstance(DataNode *node) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
DemodulatorInstance *newDemod = nullptr;
DemodulatorInstancePtr newDemod = nullptr;
node->rewindAll();

View File

@ -16,23 +16,32 @@ public:
DemodulatorMgr();
~DemodulatorMgr();
DemodulatorInstance *newThread();
std::vector<DemodulatorInstance *> &getDemodulators();
std::vector<DemodulatorInstance *> getOrderedDemodulators(bool actives = true);
std::vector<DemodulatorInstance *> getDemodulatorsAt(long long freq, int bandwidth);
DemodulatorInstance *getPreviousDemodulator(DemodulatorInstance *demod, bool actives = true);
DemodulatorInstance *getNextDemodulator(DemodulatorInstance *demod, bool actives = true);
DemodulatorInstance *getLastDemodulator();
DemodulatorInstance *getFirstDemodulator();
DemodulatorInstancePtr newThread();
//return snapshot-copy of the list purposefully
std::vector<DemodulatorInstancePtr> getDemodulators();
std::vector<DemodulatorInstancePtr> getOrderedDemodulators(bool actives = true);
std::vector<DemodulatorInstancePtr> getDemodulatorsAt(long long freq, int bandwidth);
DemodulatorInstancePtr getPreviousDemodulator(DemodulatorInstancePtr demod, bool actives = true);
DemodulatorInstancePtr getNextDemodulator(DemodulatorInstancePtr demod, bool actives = true);
DemodulatorInstancePtr getLastDemodulator();
DemodulatorInstancePtr getFirstDemodulator();
bool anyDemodulatorsAt(long long freq, int bandwidth);
void deleteThread(DemodulatorInstance *);
void deleteThread(DemodulatorInstancePtr);
void terminateAll();
void setActiveDemodulator(DemodulatorInstance *demod, bool temporary = true);
DemodulatorInstance *getActiveDemodulator();
DemodulatorInstance *getLastActiveDemodulator();
DemodulatorInstance *getLastDemodulatorWith(const std::string& type,
void setActiveDemodulator(DemodulatorInstancePtr demod, bool temporary = true);
//Dangerous: this is only intended by some internal classes,
// and only set a pre-existing demod
void setActiveDemodulatorByRawPointer(DemodulatorInstance* demod, bool temporary = true);
DemodulatorInstancePtr getActiveDemodulator();
DemodulatorInstancePtr getLastActiveDemodulator();
DemodulatorInstancePtr getLastDemodulatorWith(const std::string& type,
const std::wstring& userLabel,
long long frequency,
int bandwidth);
@ -64,28 +73,17 @@ public:
void updateLastState();
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
void saveInstance(DataNode *node, DemodulatorInstance *inst);
void saveInstance(DataNode *node, DemodulatorInstancePtr inst);
DemodulatorInstance *loadInstance(DataNode *node);
DemodulatorInstancePtr loadInstance(DataNode *node);
//to be called periodically to cleanup removed demodulators.
//if forcedGC = true, the methods waits until
//all deleted demodulators are effectively GCed.
//else: (default) the method test for effective termination
//and GC one demod per call.
// if forcedGC = true and maxWaitForTerminationMs > 0, do not
//block the method more than maxWaitForTerminationMs millisecs before returning.
//Returns: true if forcedGC = false, else true only if all deleted demodulators were GCs before maxWaitForTerminationMs.
bool garbageCollect(bool forcedGC = false, int maxWaitForTerminationMs = 0);
private:
std::vector<DemodulatorInstance *> demods;
std::vector<DemodulatorInstance *> demods_deleted;
std::vector<DemodulatorInstancePtr> demods;
std::atomic<DemodulatorInstance *> activeDemodulator;
std::atomic<DemodulatorInstance *> lastActiveDemodulator;
std::atomic<DemodulatorInstance *> activeVisualDemodulator;
DemodulatorInstancePtr activeDemodulator;
DemodulatorInstancePtr lastActiveDemodulator;
DemodulatorInstancePtr activeVisualDemodulator;
int lastBandwidth;
std::string lastDemodType;
@ -99,9 +97,7 @@ private:
//protects access to demods lists and such, need to be recursive
//because of the usage of public re-entrant methods
std::recursive_mutex demods_busy;
std::mutex deleted_demods_busy;
std::map<std::string, ModemSettings> lastModemSettings;
std::map<int,RtAudio::DeviceInfo> outputDevices;
};

View File

@ -15,7 +15,7 @@
//50 ms
#define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000)
DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL)
DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance* parent) : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL)
{
initialized.store(false);
this->parent = parent;

View File

@ -17,7 +17,7 @@ class DemodulatorInstance;
class DemodulatorPreThread : public IOThread {
public:
DemodulatorPreThread(DemodulatorInstance *parent);
DemodulatorPreThread(DemodulatorInstance* parent);
virtual ~DemodulatorPreThread();
virtual void run();
@ -50,7 +50,9 @@ public:
void writeModemSettings(ModemSettings settings);
protected:
DemodulatorInstance *parent;
DemodulatorInstance* parent;
msresamp_crcf iqResampler;
double iqResampleRatio;
std::vector<liquid_float_complex> resampledData;

View File

@ -19,10 +19,10 @@
#include <pthread.h>
#endif
std::atomic<DemodulatorInstance *> DemodulatorThread::squelchLock(nullptr);
DemodulatorInstance* DemodulatorThread::squelchLock(nullptr);
std::mutex DemodulatorThread::squelchLockMutex;
DemodulatorThread::DemodulatorThread(DemodulatorInstance *parent)
DemodulatorThread::DemodulatorThread(DemodulatorInstance* parent)
: IOThread(), outputBuffers("DemodulatorThreadBuffers"), squelchLevel(-100),
signalLevel(-100), signalFloor(-30), signalCeil(30), squelchEnabled(false) {
@ -201,10 +201,10 @@ void DemodulatorThread::run() {
if (!squelched && !squelchBreak) {
if (wxGetApp().getSoloMode() && !wxGetApp().getAppFrame()->isUserDemodBusy()) {
std::lock_guard < std::mutex > lock(squelchLockMutex);
if (squelchLock.load() == nullptr) {
squelchLock.store(demodInstance);
if (squelchLock == nullptr) {
squelchLock = demodInstance;
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
wxGetApp().getDemodMgr().setActiveDemodulator(demodInstance, false);
wxGetApp().getDemodMgr().setActiveDemodulatorByRawPointer(demodInstance, false);
squelchBreak = true;
demodInstance->getVisualCue()->triggerSquelchBreak(120);
}
@ -310,7 +310,7 @@ void DemodulatorThread::run() {
}
if (ati != nullptr) {
if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator()))) {
if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator().get()))) {
//non-blocking push needed for audio out
if (!audioOutputQueue->try_push(ati)) {
@ -385,9 +385,11 @@ bool DemodulatorThread::getSquelchBreak() {
return squelchBreak;
}
void DemodulatorThread::releaseSquelchLock(DemodulatorInstance *inst) {
void DemodulatorThread::releaseSquelchLock(DemodulatorInstance* inst) {
std::lock_guard < std::mutex > lock(squelchLockMutex);
if (inst == nullptr || squelchLock.load() == inst) {
squelchLock.store(nullptr);
if (inst == nullptr || squelchLock == inst) {
squelchLock = nullptr;
}
}

View File

@ -11,10 +11,6 @@
#include "AudioThread.h"
#include "Modem.h"
typedef ThreadBlockingQueue<AudioThreadInputPtr> DemodulatorThreadOutputQueue;
typedef std::shared_ptr<DemodulatorThreadOutputQueue> DemodulatorThreadOutputQueuePtr;
#define DEMOD_VIS_SIZE 2048
#define DEMOD_SIGNAL_MIN -30
#define DEMOD_SIGNAL_MAX 30
@ -24,7 +20,7 @@ class DemodulatorInstance;
class DemodulatorThread : public IOThread {
public:
DemodulatorThread(DemodulatorInstance *parent);
DemodulatorThread(DemodulatorInstance* parent);
virtual ~DemodulatorThread();
void onBindOutput(std::string name, ThreadQueueBasePtr threadQueue);
@ -43,13 +39,14 @@ public:
bool getSquelchBreak();
static void releaseSquelchLock(DemodulatorInstance *inst);
static void releaseSquelchLock(DemodulatorInstance* inst);
protected:
double abMagnitude(float inphase, float quadrature);
double linearToDb(double linear);
DemodulatorInstance *demodInstance = nullptr;
DemodulatorInstance* demodInstance;
ReBuffer<AudioThreadInput> outputBuffers;
std::atomic_bool muted;
@ -58,7 +55,7 @@ protected:
std::atomic<float> signalLevel, signalFloor, signalCeil;
bool squelchEnabled, squelchBreak;
static std::atomic<DemodulatorInstance *> squelchLock;
static DemodulatorInstance* squelchLock;
static std::mutex squelchLockMutex;

View File

@ -9,9 +9,6 @@
//50 ms
#define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000)
//1s
#define MAX_BLOCKING_DURATION_MICROS (1000 * 1000)
DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(),
commandQueue(nullptr), resultQueue(nullptr), cModem(nullptr), cModemKit(nullptr) {
}
@ -111,7 +108,7 @@ void DemodulatorWorkerThread::run() {
result.modemName = cModemName;
//VSO: blocking push
resultQueue->push(result, MAX_BLOCKING_DURATION_MICROS, "resultQueue");
resultQueue->push(result);
}
}
// std::cout << "Demodulator worker thread done." << std::endl;

View File

@ -348,10 +348,9 @@ wxTreeItemId BookmarkView::refreshBookmarks() {
void BookmarkView::doUpdateActiveList() {
std::vector<DemodulatorInstance *> &demods = wxGetApp().getDemodMgr().getDemodulators();
// DemodulatorInstance *activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstance *lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
auto demods = wxGetApp().getDemodMgr().getDemodulators();
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
//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.
@ -693,7 +692,8 @@ wxButton *BookmarkView::addButton(wxWindow *parent, std::string labelVal, wxObje
}
void BookmarkView::doBookmarkActive(std::string group, DemodulatorInstance *demod) {
void BookmarkView::doBookmarkActive(std::string group, DemodulatorInstancePtr demod) {
wxGetApp().getBookmarkMgr().addBookmark(group, demod);
wxGetApp().getBookmarkMgr().updateBookmarks();
}
@ -717,7 +717,7 @@ void BookmarkView::doMoveBookmark(BookmarkEntryPtr be, std::string group) {
}
void BookmarkView::doRemoveActive(DemodulatorInstance *demod) {
void BookmarkView::doRemoveActive(DemodulatorInstancePtr demod) {
wxGetApp().getBookmarkMgr().removeActive(demod);
wxGetApp().getBookmarkMgr().updateActiveList();
@ -792,7 +792,7 @@ void BookmarkView::onBookmarkChoice( wxCommandEvent & /* event */ ) {
}
void BookmarkView::activeSelection(DemodulatorInstance *dsel) {
void BookmarkView::activeSelection(DemodulatorInstancePtr dsel) {
m_frequencyVal->SetLabelText(frequencyToStr(dsel->getFrequency()));
m_bandwidthVal->SetLabelText(frequencyToStr(dsel->getBandwidth()));
@ -835,7 +835,7 @@ void BookmarkView::activateBookmark(BookmarkEntryPtr bmEnt) {
//the already existing one:
// we search among the list of existing demodulators the one matching
//bmEnt and activate it. The search is made backwards, to select the most recently created one.
DemodulatorInstance *matchingDemod = wxGetApp().getDemodMgr().getLastDemodulatorWith(
DemodulatorInstancePtr matchingDemod = wxGetApp().getDemodMgr().getLastDemodulatorWith(
bmEnt->type,
bmEnt->label,
bmEnt->frequency,
@ -845,7 +845,7 @@ void BookmarkView::activateBookmark(BookmarkEntryPtr bmEnt) {
matchingDemod = wxGetApp().getDemodMgr().loadInstance(bmEnt->node);
matchingDemod->run();
wxGetApp().bindDemodulator(matchingDemod);
wxGetApp().notifyDemodulatorsChanged();
}
matchingDemod->setActive(true);

View File

@ -43,7 +43,7 @@ public:
BookmarkEntryPtr bookmarkEnt;
BookmarkRangeEntryPtr rangeEnt;
DemodulatorInstance* demod;
DemodulatorInstancePtr demod;
std::string groupName;
};
@ -84,7 +84,7 @@ public:
static BookmarkRangeEntryPtr makeActiveRangeEntry();
protected:
void activeSelection(DemodulatorInstance *dsel);
void activeSelection(DemodulatorInstancePtr dsel);
void bookmarkSelection(BookmarkEntryPtr bmSel);
void rangeSelection(BookmarkRangeEntryPtr re);
@ -133,10 +133,10 @@ protected:
wxButton *makeButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
wxButton *addButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
void doBookmarkActive(std::string group, DemodulatorInstance *demod);
void doBookmarkActive(std::string group, DemodulatorInstancePtr demod);
void doBookmarkRecent(std::string group, BookmarkEntryPtr be);
void doMoveBookmark(BookmarkEntryPtr be, std::string group);
void doRemoveActive(DemodulatorInstance *demod);
void doRemoveActive(DemodulatorInstancePtr demod);
void doRemoveRecent(BookmarkEntryPtr be);
void doClearRecents();
@ -191,7 +191,7 @@ protected:
// Focus
BookmarkEntryPtr nextEnt;
BookmarkRangeEntryPtr nextRange;
DemodulatorInstance *nextDemod;
DemodulatorInstancePtr nextDemod;
std::string nextGroup;
// Search

View File

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

View File

@ -16,12 +16,12 @@
#define MAX_BLOCKING_DURATION_MICROS (1000 * 1000)
SDRPostThread::SDRPostThread() : IOThread(), buffers("SDRPostThreadBuffers"), visualDataBuffers("SDRPostThreadVisualDataBuffers"), frequency(0) {
iqDataInQueue = NULL;
iqDataOutQueue = NULL;
iqVisualQueue = NULL;
iqDataInQueue = nullptr;
iqDataOutQueue = nullptr;
iqVisualQueue = nullptr;
numChannels = 0;
channelizer = NULL;
channelizer = nullptr;
sampleRate = 0;
nRunDemods = 0;
@ -36,44 +36,12 @@ SDRPostThread::SDRPostThread() : IOThread(), buffers("SDRPostThreadBuffers"), vi
SDRPostThread::~SDRPostThread() {
}
void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_demod);
demodulators.push_back(demod);
void SDRPostThread::notifyDemodulatorsChanged() {
doRefresh.store(true);
}
void SDRPostThread::bindDemodulators(std::vector<DemodulatorInstance *> *demods) {
if (!demods) {
return;
}
std::lock_guard < std::mutex > lock(busy_demod);
for (std::vector<DemodulatorInstance *>::iterator di = demods->begin(); di != demods->end(); di++) {
demodulators.push_back(*di);
doRefresh.store(true);
}
}
void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
std::lock_guard < std::mutex > lock(busy_demod);
std::vector<DemodulatorInstance *>::iterator i = std::find(demodulators.begin(), demodulators.end(), demod);
if (i != demodulators.end()) {
demodulators.erase(i);
doRefresh.store(true);
}
}
void SDRPostThread::initPFBChannelizer() {
// std::cout << "Initializing post-process FIR polyphase filterbank channelizer with " << numChannels << " channels." << std::endl;
if (channelizer) {
@ -91,15 +59,16 @@ void SDRPostThread::initPFBChannelizer() {
void SDRPostThread::updateActiveDemodulators() {
// In range?
std::vector<DemodulatorInstance *>::iterator demod_i;
nRunDemods = 0;
long long centerFreq = wxGetApp().getFrequency();
for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
DemodulatorInstance *demod = *demod_i;
//retreive the current list of demodulators:
auto demodulators = wxGetApp().getDemodMgr().getDemodulators();
for (auto demod : demodulators) {
// not in range?
if (demod->isDeltaLock()) {
if (demod->getFrequency() != centerFreq + demod->getDeltaLockOfs()) {
@ -123,7 +92,7 @@ void SDRPostThread::updateActiveDemodulators() {
}
} else if (!demod->isActive()) { // in range, activate if not activated
demod->setActive(true);
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL) {
if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr) {
wxGetApp().getDemodMgr().setActiveDemodulator(demod);
}
@ -194,9 +163,8 @@ void SDRPostThread::run() {
if (!iqDataInQueue->pop(data_in, HEARTBEAT_CHECK_PERIOD_MICROS)) {
continue;
}
// std::lock_guard < std::mutex > lock(data_in->m_mutex);
std::lock_guard < std::mutex > lock(busy_demod);
bool doUpdate = false;
if (data_in && data_in->data.size()) {
if(data_in->numChannels > 1) {
@ -205,17 +173,16 @@ void SDRPostThread::run() {
runSingleCH(data_in.get());
}
}
bool doUpdate = false;
for (size_t j = 0; j < nRunDemods; j++) {
DemodulatorInstance *demod = runDemods[j];
DemodulatorInstancePtr demod = runDemods[j];
if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
doUpdate = true;
}
}
//Only update the list of demodulators here
if (doUpdate) {
if (doUpdate || doRefresh) {
updateActiveDemodulators();
}
} //end while
@ -264,9 +231,9 @@ void SDRPostThread::runSingleCH(SDRThreadIQData *data_in) {
}
size_t refCount = nRunDemods;
bool doIQDataOut = (iqDataOutQueue != NULL && !iqDataOutQueue->full());
bool doDemodVisOut = (nRunDemods && iqActiveDemodVisualQueue != NULL && !iqActiveDemodVisualQueue->full());
bool doVisOut = (iqVisualQueue != NULL && !iqVisualQueue->full());
bool doIQDataOut = (iqDataOutQueue != nullptr && !iqDataOutQueue->full());
bool doDemodVisOut = (nRunDemods && iqActiveDemodVisualQueue != nullptr && !iqActiveDemodVisualQueue->full());
bool doVisOut = (iqVisualQueue != nullptr && !iqVisualQueue->full());
if (doIQDataOut) {
refCount++;
@ -295,22 +262,26 @@ void SDRPostThread::runSingleCH(SDRThreadIQData *data_in) {
if (doDemodVisOut) {
//VSO: blocking push
iqActiveDemodVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() iqActiveDemodVisualQueue");
iqActiveDemodVisualQueue->push(demodDataOut);
}
if (doIQDataOut) {
//VSO: blocking push
iqDataOutQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS,"runSingleCH() iqDataOutQueue");
iqDataOutQueue->push(demodDataOut);
}
if (doVisOut) {
//VSO: blocking push
iqVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() iqVisualQueue");
iqVisualQueue->push(demodDataOut);
}
for (size_t i = 0; i < nRunDemods; i++) {
//VSO: blocking push
runDemods[i]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() runDemods[i]->getIQInputDataPipe()");
//VSO: timed-push
if (!runDemods[i]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runSingleCH() runDemods[i]->getIQInputDataPipe()")) {
//some runDemods are no longer there, bail out from runSingleCH() entirely.
doRefresh = true;
return;
}
}
}
}
@ -338,7 +309,7 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
bool doVis = false;
if (iqVisualQueue != NULL && !iqVisualQueue->full()) {
if (iqVisualQueue != nullptr && !iqVisualQueue->full()) {
doVis = true;
}
@ -347,11 +318,11 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
iqDataOut->data.assign(data_in->data.begin(), data_in->data.begin() + dataSize);
//VSO: blocking push
iqDataOutQueue->push(iqDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqDataOutQueue");
iqDataOutQueue->push(iqDataOut);
if (doVis) {
//VSO: blocking push
iqVisualQueue->push(iqDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqVisualQueue");
iqVisualQueue->push(iqDataOut);
}
}
@ -366,7 +337,7 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
doRefresh.store(false);
}
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
int activeDemodChannel = -1;
// Find active demodulators
@ -384,7 +355,7 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
// Find nearest channel for each demodulator
for (size_t i = 0; i < nRunDemods; i++) {
DemodulatorInstance *demod = runDemods[i];
DemodulatorInstancePtr demod = runDemods[i];
demodChannel[i] = getChannelAt(demod->getFrequency());
if (demod == activeDemod) {
activeDemodChannel = demodChannel[i];
@ -400,7 +371,7 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
// Run channels
for (int i = 0; i < numChannels+1; i++) {
int doDemodVis = ((activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full())?1:0;
int doDemodVis = ((activeDemodChannel == i) && (iqActiveDemodVisualQueue != nullptr) && !iqActiveDemodVisualQueue->full())?1:0;
if (!doDemodVis && demodChannelActive[i] == 0) {
continue;
@ -447,16 +418,20 @@ void SDRPostThread::runPFBCH(SDRThreadIQData *data_in) {
if (doDemodVis) {
//VSO: blocking push
iqActiveDemodVisualQueue->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() iqActiveDemodVisualQueue");
iqActiveDemodVisualQueue->push(demodDataOut);
}
for (size_t j = 0; j < nRunDemods; j++) {
if (demodChannel[j] == i) {
DemodulatorInstance *demod = runDemods[j];
//VSO: blocking push
demod->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() demod->getIQInputDataPipe()");
//VSO: timed- push
if (!runDemods[j]->getIQInputDataPipe()->push(demodDataOut, MAX_BLOCKING_DURATION_MICROS, "runPFBCH() runDemods[j]->getIQInputDataPipe()")) {
//Some runDemods are no longer there, bail out from runPFBCH() entirely.
doRefresh = true;
return;
}
}
}
} //end for
}
}
}

View File

@ -11,10 +11,8 @@ public:
SDRPostThread();
~SDRPostThread();
void bindDemodulator(DemodulatorInstance *demod);
void bindDemodulators(std::vector<DemodulatorInstance *> *demods);
void removeDemodulator(DemodulatorInstance *demod);
void notifyDemodulatorsChanged();
virtual void run();
virtual void terminate();
@ -27,12 +25,6 @@ protected:
DemodulatorThreadInputQueuePtr iqDataOutQueue;
DemodulatorThreadInputQueuePtr iqVisualQueue;
DemodulatorThreadInputQueuePtr iqActiveDemodVisualQueue;
//protects access to demodulators lists and such
std::mutex busy_demod;
std::vector<DemodulatorInstance *> demodulators;
private:
@ -48,7 +40,7 @@ private:
long long chanBw = 0;
size_t nRunDemods;
std::vector<DemodulatorInstance *> runDemods;
std::vector<DemodulatorInstancePtr> runDemods;
std::vector<int> demodChannel;
std::vector<int> demodChannelActive;

View File

@ -13,10 +13,10 @@
#define TARGET_DISPLAY_FPS 60
SDRThread::SDRThread() : IOThread(), buffers("SDRThreadBuffers") {
device = NULL;
device = nullptr;
deviceConfig.store(NULL);
deviceInfo.store(NULL);
deviceConfig.store(nullptr);
deviceInfo.store(nullptr);
sampleRate.store(DEFAULT_SAMPLE_RATE);
frequency.store(0);

View File

@ -62,7 +62,7 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas, wxGLContext *sharedContex
//#endif
}
void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, long long center_freq, long long srate, bool centerline) {
void PrimaryGLContext::DrawDemodInfo(DemodulatorInstancePtr demod, RGBA4f color, long long center_freq, long long srate, bool centerline) {
if (!demod) {
return;
}
@ -287,7 +287,7 @@ void PrimaryGLContext::DrawFreqBwInfo(long long freq, int bw, RGBA4f color, long
glDisable(GL_BLEND);
}
void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBA4f color, long long center_freq, long long srate) {
void PrimaryGLContext::DrawDemod(DemodulatorInstancePtr demod, RGBA4f color, long long center_freq, long long srate) {
if (!demod) {
return;
}
@ -409,7 +409,8 @@ void PrimaryGLContext::drawSingleDemodLabel(const std::wstring& demodStr, float
}
void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long long /* center_freq */, long long srate) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
long long bw = 0;

View File

@ -26,9 +26,9 @@ public:
void DrawFreqSelector(float uxPos, RGBA4f color, float w = 0, long long center_freq = -1, long long srate = 0);
void DrawRangeSelector(float uxPos1, float uxPos2, RGBA4f color);
void DrawDemod(DemodulatorInstance *demod, RGBA4f color, long long center_freq = -1, long long srate = 0);
void DrawDemod(DemodulatorInstancePtr demod, RGBA4f color, long long center_freq = -1, long long srate = 0);
void DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, long long center_freq = -1, long long srate = 0, bool centerline = false);
void DrawDemodInfo(DemodulatorInstancePtr demod, RGBA4f color, long long center_freq = -1, long long srate = 0, bool centerline = false);
void DrawFreqBwInfo(long long freq, int bw, RGBA4f color, long long center_freq = - 1, long long srate = 0, bool stack = false, bool centerline = false);
void setHoverAlpha(float hoverAlpha);

View File

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

View File

@ -61,7 +61,8 @@ TuningCanvas::~TuningCanvas() {
}
bool TuningCanvas::changed() {
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
long long current_freq = 0;
if (activeDemod != NULL) {
@ -92,7 +93,7 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->DrawBegin();
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
freq = 0;
if (activeDemod != NULL) {
@ -170,7 +171,7 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) {
amount *= 2;
}
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
auto activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (state == TUNING_HOVER_FREQ && activeDemod) {
long long freq = activeDemod->getFrequency();
long long diff = abs(wxGetApp().getFrequency() - freq);
@ -330,7 +331,7 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) {
if (hoverState == TUNING_HOVER_BW || hoverState == TUNING_HOVER_FREQ) {
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getLastActiveDemodulator());
} else {
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
}
}
@ -400,7 +401,7 @@ void TuningCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
SetCursor(wxCURSOR_CROSS);
hoverIndex = 0;
hoverState = TUNING_HOVER_NONE;
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
if (currentPPM != lastPPM) {
wxGetApp().saveConfig();

View File

@ -24,6 +24,8 @@
#include <wx/numformatter.h>
#include "DemodulatorThread.h"
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas)
EVT_PAINT(WaterfallCanvas::OnPaint)
EVT_IDLE(WaterfallCanvas::OnIdle)
@ -263,10 +265,10 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
waterfallPanel.calcTransform(CubicVR::mat4::identity());
waterfallPanel.draw();
std::vector<DemodulatorInstance *> &demods = wxGetApp().getDemodMgr().getDemodulators();
auto demods = wxGetApp().getDemodMgr().getDemodulators();
DemodulatorInstance *activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstance *lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
auto activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator();
auto lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
bool isNew = shiftDown
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
@ -307,9 +309,9 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
}
} else {
if (lastActiveDemodulator) {
glContext->DrawDemod(lastActiveDemodulator, ((isNew && activeDemodulator == NULL) || (activeDemodulator != NULL))?currentTheme->waterfallHighlight:currentTheme->waterfallDestroy, currentCenterFreq, currentBandwidth);
glContext->DrawDemod(lastActiveDemodulator, ((isNew && activeDemodulator == nullptr) || (activeDemodulator != nullptr))?currentTheme->waterfallHighlight:currentTheme->waterfallDestroy, currentCenterFreq, currentBandwidth);
}
if (activeDemodulator == NULL) {
if (activeDemodulator == nullptr) {
glContext->DrawFreqSelector(mouseTracker.getMouseX(), ((isNew && lastActiveDemodulator) || (!lastActiveDemodulator) )?currentTheme->waterfallNew:currentTheme->waterfallHover, 0, currentCenterFreq, currentBandwidth);
} else {
glContext->DrawDemod(activeDemodulator, currentTheme->waterfallHover, currentCenterFreq, currentBandwidth);
@ -390,7 +392,7 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
InteractiveCanvas::OnKeyDown(event);
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
auto activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
long long originalFreq = getCenterFrequency();
long long freq = originalFreq;
@ -490,9 +492,9 @@ void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
void WaterfallCanvas::updateHoverState() {
long long freqPos = getFrequencyAt(mouseTracker.getMouseX());
std::vector<DemodulatorInstance *> demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000);
auto demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000);
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
if (altDown) {
nextDragState = WF_DRAG_RANGE;
@ -506,10 +508,10 @@ void WaterfallCanvas::updateHoverState() {
} else if (demodsHover.size() && !shiftDown) {
long near_dist = getBandwidth();
DemodulatorInstance *activeDemodulator = NULL;
DemodulatorInstancePtr activeDemodulator = nullptr;
for (int i = 0, iMax = demodsHover.size(); i < iMax; i++) {
DemodulatorInstance *demod = demodsHover[i];
auto demod = demodsHover[i];
long long freqDiff = demod->getFrequency() - freqPos;
long halfBw = (demod->getBandwidth() / 2);
long long currentBw = getBandwidth();
@ -537,7 +539,7 @@ void WaterfallCanvas::updateHoverState() {
}
}
if (activeDemodulator == NULL) {
if (activeDemodulator == nullptr) {
nextDragState = WF_DRAG_NONE;
SetCursor(wxCURSOR_CROSS);
return;
@ -588,10 +590,10 @@ void WaterfallCanvas::updateHoverState() {
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
InteractiveCanvas::OnMouseMoved(event);
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator();
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator();
if (mouseTracker.mouseDown()) {
if (demod == NULL) {
if (demod == nullptr) {
return;
}
if (dragState == WF_DRAG_BANDWIDTH_LEFT || dragState == WF_DRAG_BANDWIDTH_RIGHT) {
@ -650,7 +652,7 @@ void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) {
wxGetApp().getDemodMgr().updateLastState();
if (dragState && dragState != WF_DRAG_RANGE) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator();
auto demod = wxGetApp().getDemodMgr().getActiveDemodulator();
if (demod) {
dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency();
dragBW = demod->getBandwidth();
@ -670,14 +672,14 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
InteractiveCanvas::OnMouseReleased(event);
wxGetApp().getDemodMgr().updateLastState();
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL)
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() == nullptr)
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
mouseTracker.setVertDragLock(false);
mouseTracker.setHorizDragLock(false);
DemodulatorInstance *demod = isNew?NULL:wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstance *activeDemod = isNew?NULL:wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstancePtr demod = isNew?nullptr:wxGetApp().getDemodMgr().getLastActiveDemodulator();
DemodulatorInstancePtr activeDemod = isNew?nullptr:wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorMgr *mgr = &wxGetApp().getDemodMgr();
@ -727,7 +729,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType()));
demod->run();
wxGetApp().bindDemodulator(demod);
wxGetApp().notifyDemodulatorsChanged();
DemodulatorThread::releaseSquelchLock(nullptr);
}
@ -827,10 +829,10 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->run();
wxGetApp().bindDemodulator(demod);
wxGetApp().notifyDemodulatorsChanged();
}
if (demod == NULL) {
if (demod == nullptr) {
dragState = WF_DRAG_NONE;
return;
}
@ -850,7 +852,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
void WaterfallCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
InteractiveCanvas::OnMouseLeftWindow(event);
SetCursor(wxCURSOR_CROSS);
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr);
mouseZoom = 1.0;
}