FIX: missing demod displays due to wrong input/queue setups order

This commit is contained in:
vsonnier 2017-01-08 12:46:31 +01:00
parent 4919988c7c
commit 1a53e454ab
4 changed files with 45 additions and 15 deletions

View File

@ -281,7 +281,7 @@ AppFrame::AppFrame() :
// vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0); // vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0);
// vbox->AddSpacer(1); // vbox->AddSpacer(1);
bookmarkSplitter = new wxSplitterWindow( mainSplitter, wxID_BM_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE ); bookmarkSplitter = new wxSplitterWindow(mainSplitter, wxID_BM_SPLITTER, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH | wxSP_LIVE_UPDATE );
bookmarkSplitter->SetMinimumPaneSize(1); bookmarkSplitter->SetMinimumPaneSize(1);
bookmarkSplitter->SetSashGravity(1.0f / 20.0f); bookmarkSplitter->SetSashGravity(1.0f / 20.0f);
@ -1395,7 +1395,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
demodGainMeter->setInputValue(demod->getGain()); demodGainMeter->setInputValue(demod->getGain());
wxGetApp().getDemodMgr().setLastGain(demod->getGain()); wxGetApp().getDemodMgr().setLastGain(demod->getGain());
int outputDevice = demod->getOutputDevice(); int outputDevice = demod->getOutputDevice();
if (scopeCanvas) scopeCanvas->setDeviceName(outputDevices[outputDevice].name); if (scopeCanvas) {
scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
}
// outputDeviceMenuItems[outputDevice]->Check(true); // outputDeviceMenuItems[outputDevice]->Check(true);
std::string dType = demod->getDemodulatorType(); std::string dType = demod->getDemodulatorType();
demodModeSelector->setSelection(dType); demodModeSelector->setSelection(dType);
@ -1575,12 +1577,16 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
if (demodWaterfallCanvas && wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) { if (demodWaterfallCanvas && wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency()); demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
if (demodSpectrumCanvas) demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency()); if (demodSpectrumCanvas) {
demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
}
} }
if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) { if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) {
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency()); spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency()); waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
} }
if (demodMuteButton->modeChanged()) { if (demodMuteButton->modeChanged()) {
int muteMode = demodMuteButton->getSelection(); int muteMode = demodMuteButton->getSelection();
if (muteMode == -1) { if (muteMode == -1) {
@ -1685,7 +1691,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
wxGetApp().getSpectrumProcessor()->setPeakHold(peakHoldMode == 1); wxGetApp().getSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
//make the peak hold act on the current dmod also, like a zoomed-in version. //make the peak hold act on the current dmod also, like a zoomed-in version.
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1); if (wxGetApp().getDemodSpectrumProcessor()) {
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(peakHoldMode == 1);
}
peakHoldButton->clearModeChanged(); peakHoldButton->clearModeChanged();
} }
@ -1933,7 +1941,9 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) {
} }
void AppFrame::setScopeDeviceName(std::string deviceName) { void AppFrame::setScopeDeviceName(std::string deviceName) {
if (scopeCanvas) scopeCanvas->setDeviceName(deviceName); if (scopeCanvas) {
scopeCanvas->setDeviceName(deviceName);
}
} }
@ -2199,7 +2209,9 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
break; break;
case 'P': case 'P':
wxGetApp().getSpectrumProcessor()->setPeakHold(!wxGetApp().getSpectrumProcessor()->getPeakHold()); wxGetApp().getSpectrumProcessor()->setPeakHold(!wxGetApp().getSpectrumProcessor()->getPeakHold());
if (wxGetApp().getDemodSpectrumProcessor()) wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold()); if (wxGetApp().getDemodSpectrumProcessor()) {
wxGetApp().getDemodSpectrumProcessor()->setPeakHold(wxGetApp().getSpectrumProcessor()->getPeakHold());
}
peakHoldButton->setSelection(wxGetApp().getSpectrumProcessor()->getPeakHold()?1:0); peakHoldButton->setSelection(wxGetApp().getSpectrumProcessor()->getPeakHold()?1:0);
peakHoldButton->clearModeChanged(); peakHoldButton->clearModeChanged();
break; break;

View File

@ -301,7 +301,6 @@ bool CubicSDR::OnInit() {
getSpectrumProcessor()->setInput(pipeIQVisualData); getSpectrumProcessor()->setInput(pipeIQVisualData);
getSpectrumProcessor()->setHideDC(true); getSpectrumProcessor()->setHideDC(true);
// I/Q Data // I/Q Data
pipeSDRIQData = new SDRThreadIQDataQueue(); pipeSDRIQData = new SDRThreadIQDataQueue();
pipeSDRIQData->set_max_num_items(100); pipeSDRIQData->set_max_num_items(100);
@ -314,10 +313,7 @@ bool CubicSDR::OnInit() {
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData); sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData); sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
#if CUBICSDR_ENABLE_VIEW_SCOPE #if CUBICSDR_ENABLE_VIEW_SCOPE
pipeAudioVisualData = new DemodulatorThreadOutputQueue(); pipeAudioVisualData = new DemodulatorThreadOutputQueue();
pipeAudioVisualData->set_max_num_items(1); pipeAudioVisualData->set_max_num_items(1);
@ -331,15 +327,29 @@ bool CubicSDR::OnInit() {
demodVisualThread = new SpectrumVisualDataThread(); demodVisualThread = new SpectrumVisualDataThread();
pipeDemodIQVisualData = new DemodulatorThreadInputQueue(); pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
pipeDemodIQVisualData->set_max_num_items(1); pipeDemodIQVisualData->set_max_num_items(1);
if (getDemodSpectrumProcessor()) getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
if (getDemodSpectrumProcessor()) {
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
}
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData); sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
#else #else
demodVisualThread = nullptr; demodVisualThread = nullptr;
pipeDemodIQVisualData = nullptr; pipeDemodIQVisualData = nullptr;
t_DemodVisual = nullptr; t_DemodVisual = nullptr;
#endif #endif
// Now that input/output queue plumbing is completely done, we can
//safely starts all the threads:
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
if (demodVisualThread != nullptr) {
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
}
//Start SDRPostThread last.
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
sdrEnum = new SDREnumerator(); sdrEnum = new SDREnumerator();
SDREnumerator::setManuals(config.getManualDevices()); SDREnumerator::setManuals(config.getManualDevices());

View File

@ -72,7 +72,7 @@ void IOThread::terminate() {
}; };
void IOThread::onBindOutput(std::string /* name */, ThreadQueueBase* /* threadQueue */) { void IOThread::onBindOutput(std::string /* name */, ThreadQueueBase* /* threadQueue */) {
}; };
void IOThread::onBindInput(std::string /* name */, ThreadQueueBase* /* threadQueue */) { void IOThread::onBindInput(std::string /* name */, ThreadQueueBase* /* threadQueue */) {
@ -80,20 +80,24 @@ void IOThread::onBindInput(std::string /* name */, ThreadQueueBase* /* threadQue
}; };
void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) { void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
input_queues[qname] = threadQueue; input_queues[qname] = threadQueue;
this->onBindInput(qname, threadQueue); this->onBindInput(qname, threadQueue);
}; };
ThreadQueueBase *IOThread::getInputQueue(std::string qname) { ThreadQueueBase *IOThread::getInputQueue(std::string qname) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
return input_queues[qname]; return input_queues[qname];
}; };
void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) { void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
output_queues[qname] = threadQueue; output_queues[qname] = threadQueue;
this->onBindOutput(qname, threadQueue); this->onBindOutput(qname, threadQueue);
}; };
ThreadQueueBase *IOThread::getOutputQueue(std::string qname) { ThreadQueueBase *IOThread::getOutputQueue(std::string qname) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
return output_queues[qname]; return output_queues[qname];
}; };

View File

@ -221,7 +221,10 @@ public:
protected: protected:
std::map<std::string, ThreadQueueBase *, map_string_less> input_queues; std::map<std::string, ThreadQueueBase *, map_string_less> input_queues;
std::map<std::string, ThreadQueueBase *, map_string_less> output_queues; std::map<std::string, ThreadQueueBase *, map_string_less> output_queues;
//this protects against concurrent changes in input/output bindings: get/set/Input/OutPutQueue
mutable std::mutex m_queue_bindings_mutex;
//true when a termination is ordered //true when a termination is ordered
std::atomic_bool stopping; std::atomic_bool stopping;
Timer gTimer; Timer gTimer;
@ -230,4 +233,5 @@ private:
//true when the thread has really ended, i.e run() from threadMain() has returned. //true when the thread has really ended, i.e run() from threadMain() has returned.
std::atomic_bool terminated; std::atomic_bool terminated;
}; };